[OpenWrt-Devel] [PATCH 1/3] brcm2708: switch to linux 4.4 and update patches

Álvaro Fernández Rojas noltari at gmail.com
Sun Feb 21 07:38:18 EST 2016


As usual these patches were extracted from:
https://github.com/raspberrypi/linux/commits/rpi-4.4.y

Signed-off-by: Álvaro Fernández Rojas <noltari at gmail.com>
---
 target/linux/brcm2708/Makefile                     |      2 +-
 ...0001-smsx95xx-fix-crimes-against-truesize.patch |      4 +-
 ...02-smsc95xx-Disable-turbo-mode-by-default.patch |      4 +-
 ...around-for-issue-where-dirty-page-count-g.patch |      4 +-
 .../0004-BCM2835_DT-Fix-I2S-register-map.patch     |      4 +-
 ...-Prevent-spurious-interrupts-and-trap-the.patch |      4 +-
 .../0006-irqchip-bcm2835-Add-FIQ-support.patch     |      4 +-
 ...-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch |      4 +-
 ...erial-8250-Don-t-crash-when-nr_uarts-is-0.patch |      4 +-
 ...2835-Set-base-to-0-give-expected-gpio-num.patch |      4 +-
 ...2835-Fix-interrupt-handling-for-GPIOs-28-.patch |      4 +-
 ...2835-Only-request-the-interrupts-listed-i.patch |      4 +-
 ...cm2835-Support-pin-groups-other-than-7-11.patch |      4 +-
 ...RM-bcm2835-Set-Serial-number-and-Revision.patch |      4 +-
 ...-get-base-address-for-DMA-from-devicetree.patch |      4 +-
 ...-add-24bit-support-update-bclk_ratio-to-m.patch |      4 +-
 ...s-setup-clock-only-if-CPU-is-clock-master.patch |      4 +-
 ...835-i2s-Eliminate-debugfs-directory-error.patch |      4 +-
 .../0018-bcm2835-i2s-Register-PCM-device.patch     |      4 +-
 ...i2s-Enable-MMAP-support-via-a-DT-property.patch |      4 +-
 ...0-dmaengine-bcm2835-Add-slave-dma-support.patch |      4 +-
 ...ine-bcm2835-set-residue_granularity-field.patch |      4 +-
 ...cm2835-Load-driver-early-and-support-lega.patch |      4 +-
 ...-dma-Fix-dreq-not-set-for-slave-transfers.patch |      4 +-
 ...-Limit-cyclic-transfers-on-lite-channels-.patch |      4 +-
 .../0025-bcm2835-Add-support-for-uart1.patch       |      4 +-
 ...irmware-bcm2835-Add-missing-property-tags.patch |      4 +-
 .../0027-Main-bcm2708-bcm2709-linux-port.patch     |      4 +-
 ...-squash-include-ARCH_BCM2708-ARCH_BCM2709.patch |      4 +-
 .../patches-4.4/0029-Add-dwc_otg-driver.patch      |      4 +-
 .../0030-bcm2708-framebuffer-driver.patch          |      4 +-
 .../0031-dmaengine-Add-support-for-BCM2708.patch   |      4 +-
 ...-parameter-to-mmc-multi_io_quirk-callback.patch |      4 +-
 .../0033-MMC-added-alternative-MMC-driver.patch    |      4 +-
 ...835-sdhost-driver-and-an-overlay-to-enabl.patch |      4 +-
 ...ma-Add-vc_cma-driver-to-enable-use-of-CMA.patch |      4 +-
 .../0036-bcm2708-alsa-sound-driver.patch           |      4 +-
 .../patches-4.4/0037-bcm2708-vchiq-driver.patch    |      4 +-
 .../0038-vc_mem-Add-vc_mem-driver.patch            |      4 +-
 ...deoCore-shared-memory-service-for-BCM2835.patch |      4 +-
 ...omem-device-for-rootless-user-GPIO-access.patch |      4 +-
 .../brcm2708/patches-4.4/0041-Add-SMI-driver.patch |      4 +-
 .../patches-4.4/0042-Add-SMI-NAND-driver.patch     |      4 +-
 ...3-lirc-added-support-for-RaspberryPi-GPIO.patch |      4 +-
 .../patches-4.4/0044-Add-cpufreq-driver.patch      |      4 +-
 ...-thermal-driver-for-reporting-core-temper.patch |      4 +-
 .../0046-Add-Chris-Boot-s-i2c-driver.patch         |      4 +-
 .../0047-char-broadcom-Add-vcio-module.patch       |      4 +-
 ...048-firmware-bcm2835-Support-ARCH_BCM270x.patch |      4 +-
 .../0049-bcm2835-add-v4l2-camera-device.patch      |      4 +-
 ...-mkknlimg-and-knlinfo-scripts-from-tools-.patch |      4 +-
 ...port-for-the-CONFIG_CMDLINE_EXTEND-option.patch |      4 +-
 ...0052-BCM2708-Add-core-Device-Tree-support.patch |      4 +-
 ...3-bcm2835-Match-with-BCM2708-Device-Trees.patch |      4 +-
 .../0054-fbdev-add-FBIOCOPYAREA-ioctl.patch        |      4 +-
 ...nline-source-for-rtl8192cu-wireless-drive.patch | 172140 ++++++++++++++++++
 ...rf6052-PHY_RFShadowRefresh-fix-off-by-one.patch |     22 +
 ...0057-rtl8192cu-Add-PID-for-D-Link-DWA-131.patch |     19 +
 ...up-console-framebuffer-imageblit-function.patch |      4 +-
 ...9-Allow-mac-address-to-be-set-in-smsc95xx.patch |      4 +-
 ...e-realtime-clock-1-wire-chip-DS1307-and-1.patch |      4 +-
 ...061-Added-Device-IDs-for-August-DVB-T-205.patch |      4 +-
 ...le-CONFIG_MEMCG-but-leave-it-disabled-due.patch |      4 +-
 .../0063-ASoC-Add-support-for-PCM5102A-codec.patch |      4 +-
 .../0064-ASoC-Add-support-for-HifiBerry-DAC.patch  |      4 +-
 .../0065-ASoC-Add-support-for-Rpi-DAC.patch        |      4 +-
 ...-Implement-MCLK-configuration-options-add.patch |      4 +-
 ...d-support-for-HiFiBerry-Digi.-Driver-is-b.patch |      4 +-
 ...-Set-idle_bias_off-to-false-Idle-bias-has.patch |      4 +-
 ...audIO-Sound-Card-support-for-Raspberry-Pi.patch |      4 +-
 ...ce-default-mouse-polling-interval-to-60Hz.patch |      4 +-
 .../0071-Added-support-for-HiFiBerry-DAC.patch     |      4 +-
 ...r-for-HiFiBerry-Amp-amplifier-add-on-boar.patch |      4 +-
 ...ate-ds1307-driver-for-device-tree-support.patch |      4 +-
 ...Add-pwr_led-and-the-required-input-trigge.patch |      4 +-
 ...d-device-tree-compatible-string-and-an-ov.patch |      4 +-
 .../0076-Add-driver-for-rpi-proto.patch            |      4 +-
 .../0077-config-Add-default-configs.patch          |      4 +-
 .../0078-bcm2835-bcm2835_defconfig.patch           |      4 +-
 ...Add-touchscreen-driver-for-pi-LCD-display.patch |      4 +-
 ...opy_to_user-and-__copy_from_user-performa.patch |      4 +-
 ...poweroff-Allow-it-to-work-on-Raspberry-Pi.patch |      4 +-
 ...spidev-compatible-string-to-silence-warni.patch |      4 +-
 .../0083-scripts-dtc-Add-overlay-support.patch     |      4 +-
 ...fd-Add-Raspberry-Pi-Sense-HAT-core-driver.patch |      4 +-
 .../patches-4.4/0085-RaspiDAC3-support.patch       |      4 +-
 ...86-tpa6130a2-Add-headphone-switch-control.patch |      4 +-
 .../0087-irq-bcm2835-Fix-building-with-2708.patch  |      4 +-
 ..._display-add-backlight-driver-and-overlay.patch |      4 +-
 ...89-bcm2835-dma-Fix-up-convert-to-DMA-pool.patch |      4 +-
 ...ti-platform-support-for-mkknlimg-and-knli.patch |      4 +-
 ...-suport-for-3D-rendering-using-the-V3D-en.patch |      4 +-
 .../0092-drm-vc4-Force-HDMI-to-connected.patch     |      4 +-
 .../0093-drm-vc4-bo-cache-locking-fixes.patch      |      4 +-
 .../0094-drm-vc4-bo-cache-locking-cleanup.patch    |      4 +-
 ...vc4-Use-job_lock-to-protect-seqno_cb_list.patch |      4 +-
 ...c4-Drop-struct_mutex-around-CL-validation.patch |      4 +-
 ...c4-Drop-struct_mutex-around-CL-validation.patch |      4 +-
 ...dd-support-for-more-display-plane-formats.patch |      4 +-
 ...m-vc4-No-need-to-stop-the-stopped-threads.patch |      4 +-
 ...ove-extra-barrier-s-aroudn-CTnCA-CTnEA-se.patch |      4 +-
 ...rm-vc4-Fix-a-typo-in-a-V3D-debug-register.patch |      4 +-
 ...ble-VC4-modules-and-increase-CMA-size-wit.patch |      4 +-
 .../brcm2708/patches-4.4/0103-squash-fixups.patch  |      4 +-
 ...missing-vc4-kms-v3d-overlay.dtb-to-makefi.patch |      4 +-
 ...-Also-build-the-driver-for-downstream-ker.patch |      4 +-
 ...dts-Added-overlay-for-gpio_ir_recv-driver.patch |      4 +-
 ...pio-module-and-add-a-device-tree-overlay-.patch |      4 +-
 .../0108-New-overlay-for-PiScreen2r.patch          |      4 +-
 ...verlay-for-Adafruit-PiTFT-2.8-capacitive-.patch |      4 +-
 ...110-Add-support-for-the-HiFiBerry-DAC-Pro.patch |      4 +-
 .../0111-BCM270X_DT-Add-at86rf233-overlay.patch    |      4 +-
 .../0112-mm-Remove-the-PFN-busy-warning.patch      |      4 +-
 ...optional-field-in-the-driver-struct-for-G.patch |      4 +-
 ...-an-interface-for-capturing-the-GPU-state.patch |      4 +-
 ...ate-a-bunch-of-code-to-match-upstream-sub.patch |      4 +-
 ...-driver-s-gem_object_free-function-from-C.patch |      4 +-
 ...17-drm-vc4-Add-support-for-MSAA-rendering.patch |      4 +-
 ...ew-more-non-functional-changes-to-sync-to.patch |      4 +-
 ...-hpd-gpios-for-HDMI-GPIO-like-what-landed.patch |      4 +-
 ...chronize-validation-code-for-v2-submissio.patch |      4 +-
 ...use-mmc_debug-if-CONFIG_MMC_BCM2835-is-no.patch |      4 +-
 ...k-timeout-fix-modprobe-baudrate-parameter.patch |      4 +-
 ...-bcm270x_dt-Add-dwc2-and-dwc-otg-overlays.patch |      8 +-
 ...Add-the-sdtweak-overlay-for-tuning-sdhost.patch |      4 +-
 ...-Don-t-override-bus-width-capabilities-fr.patch |      4 +-
 ...0126-SDIO-overlay-add-bus_width-parameter.patch |      4 +-
 ...70X_DT-random-HWRNG-dtparam-default-is-on.patch |     21 +
 ...-bcm270x_dt-Add-dwc2-and-dwc-otg-overlays.patch |     23 -
 ...end-allowed-range-of-channels-and-sampler.patch |     37 +
 ...cm2835-restrict-channels-rate-to-8-960000.patch |     80 +
 .../0130-rpi-update-vc_vchi_audioserv_defs.h.patch |     66 +
 .../0131-bcm2835-implement-channel-map-API.patch   |    421 +
 ...835-access-controls-under-the-audio-mutex.patch |    237 +
 ...ays-use-2-4-8-channels-for-multichannel-l.patch |    139 +
 ...y-allow-stereo-if-analogue-jack-is-select.patch |     62 +
 .../0135-bcm2835-interpolate-audio-delay.patch     |     90 +
 ...ost-Add-workaround-for-odd-behaviour-on-s.patch |    137 +
 ...37-bcm2835-sdhost-Add-debug_flags-dtparam.patch |    120 +
 ...Add-sdio_overclock-parameter-to-sdio-over.patch |     69 +
 ...add-support-for-the-DT-property-wakeup-so.patch |     94 +
 .../0140-dt-overlay-add-wittypi-overlay.dts.patch  |     57 +
 ..._DT-Disable-DMA-for-bcm2835-sdhost-on-Pi2.patch |     28 +
 ...cm2708-Don-t-change-module-baudrate-param.patch |     99 +
 ...-24dB-digital-gain-to-be-applied-when-usi.patch |     99 +
 ...2x-Digital-gain-to-0dB-by-default-with-Hi.patch |     98 +
 ...M270X_DT-Adjust-overlay-README-formatting.patch |    746 +
 ...ay-README-Restore-spaces-deleted-in-error.patch |     39 +
 ...2835-Fix-cut-and-paste-error-in-pull-pars.patch |     25 +
 ...70X_DT-Disable-DMA-for-bcm2835-sdhost-on-.patch |     21 +
 .../0149-bcm2835-sdhost-Major-revision.patch       |   2070 +
 ...270X_DT-Add-dtparams-for-the-SD-interface.patch |    235 +
 ...m-xfer-length-when-buffer-larger-than-all.patch |     37 +
 ...ost-Restore-ATOMIC-flag-to-PIO-sg-mapping.patch |     32 +
 ...blk_pos-parameter-to-mmc-multi_io_quirk-c.patch |     79 +
 ...c95xx-driver-to-check-for-a-valid-MAC-add.patch |     40 +
 ...dcw_otg-Make-trimming-messages-less-noisy.patch |     31 +
 ...BCM270X_DT-at86rf233-overlay-drop-to-3MHz.patch |     36 +
 158 files changed, 177775 insertions(+), 272 deletions(-)
 create mode 100644 target/linux/brcm2708/patches-4.4/0055-Add-non-mainline-source-for-rtl8192cu-wireless-drive.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0056-rtl8192c_rf6052-PHY_RFShadowRefresh-fix-off-by-one.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0057-rtl8192cu-Add-PID-for-D-Link-DWA-131.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0127-FIXUP-BCM270X_DT-random-HWRNG-dtparam-default-is-on.patch
 delete mode 100644 target/linux/brcm2708/patches-4.4/0127-fixup-bcm270x_dt-Add-dwc2-and-dwc-otg-overlays.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0128-bcm2835-extend-allowed-range-of-channels-and-sampler.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0129-bcm2835-restrict-channels-rate-to-8-960000.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0130-rpi-update-vc_vchi_audioserv_defs.h.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0131-bcm2835-implement-channel-map-API.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0132-bcm2835-access-controls-under-the-audio-mutex.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0133-bcm2835-always-use-2-4-8-channels-for-multichannel-l.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0134-bcm2835-only-allow-stereo-if-analogue-jack-is-select.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0135-bcm2835-interpolate-audio-delay.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0136-bcm2835-sdhost-Add-workaround-for-odd-behaviour-on-s.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0137-bcm2835-sdhost-Add-debug_flags-dtparam.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0138-BCM270X_DT-Add-sdio_overclock-parameter-to-sdio-over.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0139-rtc-ds1307-add-support-for-the-DT-property-wakeup-so.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0140-dt-overlay-add-wittypi-overlay.dts.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0141-BCM270X_DT-Disable-DMA-for-bcm2835-sdhost-on-Pi2.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0142-FIXUP-i2c_bcm2708-Don-t-change-module-baudrate-param.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0143-Allow-up-to-24dB-digital-gain-to-be-applied-when-usi.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0144-Limit-PCM512x-Digital-gain-to-0dB-by-default-with-Hi.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0145-BCM270X_DT-Adjust-overlay-README-formatting.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0146-FIXUP-Overlay-README-Restore-spaces-deleted-in-error.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0147-pinctrl-bcm2835-Fix-cut-and-paste-error-in-pull-pars.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0148-Revert-BCM270X_DT-Disable-DMA-for-bcm2835-sdhost-on-.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0149-bcm2835-sdhost-Major-revision.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0150-BCM270X_DT-Add-dtparams-for-the-SD-interface.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0151-dcw_otg-trim-xfer-length-when-buffer-larger-than-all.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0152-bcm2835-sdhost-Restore-ATOMIC-flag-to-PIO-sg-mapping.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0153-Revert-Add-blk_pos-parameter-to-mmc-multi_io_quirk-c.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0154-Updated-smsc95xx-driver-to-check-for-a-valid-MAC-add.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0155-dcw_otg-Make-trimming-messages-less-noisy.patch
 create mode 100644 target/linux/brcm2708/patches-4.4/0156-BCM270X_DT-at86rf233-overlay-drop-to-3MHz.patch

diff --git a/target/linux/brcm2708/Makefile b/target/linux/brcm2708/Makefile
index 0c3cee5..f26da4f 100644
--- a/target/linux/brcm2708/Makefile
+++ b/target/linux/brcm2708/Makefile
@@ -14,7 +14,7 @@ FEATURES:=ext4 audio usb usbgadget display gpio fpu
 MAINTAINER:=Florian Fainelli <florian at openwrt.org>
 SUBTARGETS:=bcm2708 bcm2709
 
-KERNEL_PATCHVER:=4.1
+KERNEL_PATCHVER:=4.4
 
 include $(INCLUDE_DIR)/target.mk
 DEFAULT_PACKAGES += brcm2708-gpu-fw kmod-usb-hid kmod-sound-core kmod-sound-arm-bcm2835 kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1
diff --git a/target/linux/brcm2708/patches-4.4/0001-smsx95xx-fix-crimes-against-truesize.patch b/target/linux/brcm2708/patches-4.4/0001-smsx95xx-fix-crimes-against-truesize.patch
index 48cb813..38f237f 100644
--- a/target/linux/brcm2708/patches-4.4/0001-smsx95xx-fix-crimes-against-truesize.patch
+++ b/target/linux/brcm2708/patches-4.4/0001-smsx95xx-fix-crimes-against-truesize.patch
@@ -1,7 +1,7 @@
-From 8c2c0f30ef9ee0eccd3e56c6aeb110097569d5aa Mon Sep 17 00:00:00 2001
+From e01f4314ca3bad1a9e6e75011e096b2e7c9ae9c1 Mon Sep 17 00:00:00 2001
 From: Steve Glendinning <steve.glendinning at smsc.com>
 Date: Thu, 19 Feb 2015 18:47:12 +0000
-Subject: [PATCH 001/127] smsx95xx: fix crimes against truesize
+Subject: [PATCH 001/156] smsx95xx: fix crimes against truesize
 
 smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings.
 
diff --git a/target/linux/brcm2708/patches-4.4/0002-smsc95xx-Disable-turbo-mode-by-default.patch b/target/linux/brcm2708/patches-4.4/0002-smsc95xx-Disable-turbo-mode-by-default.patch
index 185da76..39a7765 100644
--- a/target/linux/brcm2708/patches-4.4/0002-smsc95xx-Disable-turbo-mode-by-default.patch
+++ b/target/linux/brcm2708/patches-4.4/0002-smsc95xx-Disable-turbo-mode-by-default.patch
@@ -1,7 +1,7 @@
-From 96f6fc6f990423f39b73013cd91f00a615315a90 Mon Sep 17 00:00:00 2001
+From 53c281914c7bb489a5dba2559bdbbdbdc25bd515 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Fri, 17 Apr 2015 16:58:45 +0100
-Subject: [PATCH 002/127] smsc95xx: Disable turbo mode by default
+Subject: [PATCH 002/156] smsc95xx: Disable turbo mode by default
 
 ---
  drivers/net/usb/smsc95xx.c | 2 +-
diff --git a/target/linux/brcm2708/patches-4.4/0003-vmstat-Workaround-for-issue-where-dirty-page-count-g.patch b/target/linux/brcm2708/patches-4.4/0003-vmstat-Workaround-for-issue-where-dirty-page-count-g.patch
index 4361b54..c3f30fa 100644
--- a/target/linux/brcm2708/patches-4.4/0003-vmstat-Workaround-for-issue-where-dirty-page-count-g.patch
+++ b/target/linux/brcm2708/patches-4.4/0003-vmstat-Workaround-for-issue-where-dirty-page-count-g.patch
@@ -1,7 +1,7 @@
-From 3ea06ff9ba42a29f37b46ced2fb90ff9e06da445 Mon Sep 17 00:00:00 2001
+From 570a13246efbcaf5f0952f8b2382166ab7677f7d Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 18 Jun 2014 13:42:01 +0100
-Subject: [PATCH 003/127] vmstat: Workaround for issue where dirty page count
+Subject: [PATCH 003/156] vmstat: Workaround for issue where dirty page count
  goes negative
 
 See:
diff --git a/target/linux/brcm2708/patches-4.4/0004-BCM2835_DT-Fix-I2S-register-map.patch b/target/linux/brcm2708/patches-4.4/0004-BCM2835_DT-Fix-I2S-register-map.patch
index 1b4a086..6542217 100644
--- a/target/linux/brcm2708/patches-4.4/0004-BCM2835_DT-Fix-I2S-register-map.patch
+++ b/target/linux/brcm2708/patches-4.4/0004-BCM2835_DT-Fix-I2S-register-map.patch
@@ -1,7 +1,7 @@
-From 6c72a609c205138b739a1484aa1a4ce6dd395c43 Mon Sep 17 00:00:00 2001
+From 030a4127de50633f29388f7cc5170537baa8a46b Mon Sep 17 00:00:00 2001
 From: Robert Tiemann <rtie at gmx.de>
 Date: Mon, 20 Jul 2015 11:01:25 +0200
-Subject: [PATCH 004/127] BCM2835_DT: Fix I2S register map
+Subject: [PATCH 004/156] BCM2835_DT: Fix I2S register map
 
 ---
  Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt   | 4 ++--
diff --git a/target/linux/brcm2708/patches-4.4/0005-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch b/target/linux/brcm2708/patches-4.4/0005-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch
index a0dc4e7..59c65dd 100644
--- a/target/linux/brcm2708/patches-4.4/0005-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch
+++ b/target/linux/brcm2708/patches-4.4/0005-irq-bcm2836-Prevent-spurious-interrupts-and-trap-the.patch
@@ -1,7 +1,7 @@
-From 38395f1ae1258743c3e0081c86bb4b65ad06dd69 Mon Sep 17 00:00:00 2001
+From 0e31e724041c5aa97de901e88eb889697605a543 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Fri, 4 Dec 2015 17:41:50 +0000
-Subject: [PATCH 005/127] irq-bcm2836: Prevent spurious interrupts, and trap
+Subject: [PATCH 005/156] irq-bcm2836: Prevent spurious interrupts, and trap
  them early
 
 The old arch-specific IRQ macros included a dsb to ensure the
diff --git a/target/linux/brcm2708/patches-4.4/0006-irqchip-bcm2835-Add-FIQ-support.patch b/target/linux/brcm2708/patches-4.4/0006-irqchip-bcm2835-Add-FIQ-support.patch
index 28ba48b..79e337b 100644
--- a/target/linux/brcm2708/patches-4.4/0006-irqchip-bcm2835-Add-FIQ-support.patch
+++ b/target/linux/brcm2708/patches-4.4/0006-irqchip-bcm2835-Add-FIQ-support.patch
@@ -1,7 +1,7 @@
-From 44b5e890373665231d9a5876966ef3a670b9efd7 Mon Sep 17 00:00:00 2001
+From 05e41ed8765557174e13c868e6bdead409452b9a Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Fri, 12 Jun 2015 19:01:05 +0200
-Subject: [PATCH 006/127] irqchip: bcm2835: Add FIQ support
+Subject: [PATCH 006/156] irqchip: bcm2835: Add FIQ support
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0007-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch b/target/linux/brcm2708/patches-4.4/0007-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
index 9fa768c..dd99a22 100644
--- a/target/linux/brcm2708/patches-4.4/0007-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
+++ b/target/linux/brcm2708/patches-4.4/0007-irqchip-irq-bcm2835-Add-2836-FIQ-support.patch
@@ -1,7 +1,7 @@
-From e3e8c56abfe6a036025f75908b63ae69d8eaed11 Mon Sep 17 00:00:00 2001
+From f5c7fd23e80638ed98babafb2c7d97df569e2bce Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Fri, 23 Oct 2015 16:26:55 +0200
-Subject: [PATCH 007/127] irqchip: irq-bcm2835: Add 2836 FIQ support
+Subject: [PATCH 007/156] irqchip: irq-bcm2835: Add 2836 FIQ support
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0008-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch b/target/linux/brcm2708/patches-4.4/0008-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
index 46bc447..ed035d2 100644
--- a/target/linux/brcm2708/patches-4.4/0008-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
+++ b/target/linux/brcm2708/patches-4.4/0008-serial-8250-Don-t-crash-when-nr_uarts-is-0.patch
@@ -1,7 +1,7 @@
-From 4bff078f28e6a2d55d18e06c0a92b0b78b8ea6cb Mon Sep 17 00:00:00 2001
+From 4db60442326172e590b3c34ab5f75f1359d42ec8 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Tue, 30 Jun 2015 14:12:42 +0100
-Subject: [PATCH 008/127] serial: 8250: Don't crash when nr_uarts is 0
+Subject: [PATCH 008/156] serial: 8250: Don't crash when nr_uarts is 0
 
 ---
  drivers/tty/serial/8250/8250_core.c | 2 ++
diff --git a/target/linux/brcm2708/patches-4.4/0009-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch b/target/linux/brcm2708/patches-4.4/0009-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
index 96381b6..7b701bf 100644
--- a/target/linux/brcm2708/patches-4.4/0009-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
+++ b/target/linux/brcm2708/patches-4.4/0009-pinctrl-bcm2835-Set-base-to-0-give-expected-gpio-num.patch
@@ -1,7 +1,7 @@
-From 91ea61bbf9285586d27442dc3b85ea34805ccf38 Mon Sep 17 00:00:00 2001
+From e1239426241dc0af5bf9c7eb25b3b5b91f8072f2 Mon Sep 17 00:00:00 2001
 From: notro <notro at tronnes.org>
 Date: Thu, 10 Jul 2014 13:59:47 +0200
-Subject: [PATCH 009/127] pinctrl-bcm2835: Set base to 0 give expected gpio
+Subject: [PATCH 009/156] pinctrl-bcm2835: Set base to 0 give expected gpio
  numbering
 
 Signed-off-by: Noralf Tronnes <notro at tronnes.org>
diff --git a/target/linux/brcm2708/patches-4.4/0010-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch b/target/linux/brcm2708/patches-4.4/0010-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
index c3a051f..45bf009 100644
--- a/target/linux/brcm2708/patches-4.4/0010-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
+++ b/target/linux/brcm2708/patches-4.4/0010-pinctrl-bcm2835-Fix-interrupt-handling-for-GPIOs-28-.patch
@@ -1,7 +1,7 @@
-From 15367f46e17775c4d736ed1cfc318218362c6a4d Mon Sep 17 00:00:00 2001
+From 0b7c13febba234187396a3a9a5af92e20deeab88 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Tue, 24 Feb 2015 13:40:50 +0000
-Subject: [PATCH 010/127] pinctrl-bcm2835: Fix interrupt handling for GPIOs
+Subject: [PATCH 010/156] pinctrl-bcm2835: Fix interrupt handling for GPIOs
  28-31 and 46-53
 
 Contrary to the documentation, the BCM2835 GPIO controller actually has
diff --git a/target/linux/brcm2708/patches-4.4/0011-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch b/target/linux/brcm2708/patches-4.4/0011-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
index 0ef4ba2..3e751bd 100644
--- a/target/linux/brcm2708/patches-4.4/0011-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
+++ b/target/linux/brcm2708/patches-4.4/0011-pinctrl-bcm2835-Only-request-the-interrupts-listed-i.patch
@@ -1,7 +1,7 @@
-From 167da31b9a7d3111c83993e4d614bb95bbefdcbb Mon Sep 17 00:00:00 2001
+From a5cbd1b6abdf86be640d0f312e69046c3e4907f8 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Thu, 26 Feb 2015 09:58:22 +0000
-Subject: [PATCH 011/127] pinctrl-bcm2835: Only request the interrupts listed
+Subject: [PATCH 011/156] pinctrl-bcm2835: Only request the interrupts listed
  in the DTB
 
 Although the GPIO controller can generate three interrupts (four counting
diff --git a/target/linux/brcm2708/patches-4.4/0012-spi-bcm2835-Support-pin-groups-other-than-7-11.patch b/target/linux/brcm2708/patches-4.4/0012-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
index 73e2781..d9aeadc 100644
--- a/target/linux/brcm2708/patches-4.4/0012-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
+++ b/target/linux/brcm2708/patches-4.4/0012-spi-bcm2835-Support-pin-groups-other-than-7-11.patch
@@ -1,7 +1,7 @@
-From bc9d2c297e886dfcc340414a61de970942ad7319 Mon Sep 17 00:00:00 2001
+From dd2680dc2e5fd417101093c6618cc5c14ad8f949 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Wed, 24 Jun 2015 14:10:44 +0100
-Subject: [PATCH 012/127] spi-bcm2835: Support pin groups other than 7-11
+Subject: [PATCH 012/156] spi-bcm2835: Support pin groups other than 7-11
 
 The spi-bcm2835 driver automatically uses GPIO chip-selects due to
 some unreliability of the native ones. In doing so it chooses the
diff --git a/target/linux/brcm2708/patches-4.4/0013-ARM-bcm2835-Set-Serial-number-and-Revision.patch b/target/linux/brcm2708/patches-4.4/0013-ARM-bcm2835-Set-Serial-number-and-Revision.patch
index e2b55b6..4244563 100644
--- a/target/linux/brcm2708/patches-4.4/0013-ARM-bcm2835-Set-Serial-number-and-Revision.patch
+++ b/target/linux/brcm2708/patches-4.4/0013-ARM-bcm2835-Set-Serial-number-and-Revision.patch
@@ -1,7 +1,7 @@
-From e04c4837cde13f4782fc5a274599f580d8a29715 Mon Sep 17 00:00:00 2001
+From 95d71f47cc485c5d0030291b9388bbdbdc335437 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Wed, 3 Jun 2015 12:26:13 +0200
-Subject: [PATCH 013/127] ARM: bcm2835: Set Serial number and Revision
+Subject: [PATCH 013/156] ARM: bcm2835: Set Serial number and Revision
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0014-bcm2835-i2s-get-base-address-for-DMA-from-devicetree.patch b/target/linux/brcm2708/patches-4.4/0014-bcm2835-i2s-get-base-address-for-DMA-from-devicetree.patch
index 0c36bda..d113853 100644
--- a/target/linux/brcm2708/patches-4.4/0014-bcm2835-i2s-get-base-address-for-DMA-from-devicetree.patch
+++ b/target/linux/brcm2708/patches-4.4/0014-bcm2835-i2s-get-base-address-for-DMA-from-devicetree.patch
@@ -1,7 +1,7 @@
-From c8225021ad8a8e8d2b4560bed644c5552f9f6684 Mon Sep 17 00:00:00 2001
+From 5d6a70aac1ff4f0c898131100599340c1c3aba25 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 16:44:05 +0200
-Subject: [PATCH 014/127] bcm2835-i2s: get base address for DMA from devicetree
+Subject: [PATCH 014/156] bcm2835-i2s: get base address for DMA from devicetree
 
 Code copied from spi-bcm2835. Get physical address from devicetree
 instead of using hardcoded constant.
diff --git a/target/linux/brcm2708/patches-4.4/0015-bcm2835-i2s-add-24bit-support-update-bclk_ratio-to-m.patch b/target/linux/brcm2708/patches-4.4/0015-bcm2835-i2s-add-24bit-support-update-bclk_ratio-to-m.patch
index b627327..f7e4711 100644
--- a/target/linux/brcm2708/patches-4.4/0015-bcm2835-i2s-add-24bit-support-update-bclk_ratio-to-m.patch
+++ b/target/linux/brcm2708/patches-4.4/0015-bcm2835-i2s-add-24bit-support-update-bclk_ratio-to-m.patch
@@ -1,7 +1,7 @@
-From 328b2e8b8a38fe62431c2ad5ae22cee31740b10d Mon Sep 17 00:00:00 2001
+From e7f330a7e837e0d6e31cb85dbaeace60ebd8cad1 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 15:21:16 +0200
-Subject: [PATCH 015/127] bcm2835-i2s: add 24bit support, update bclk_ratio to
+Subject: [PATCH 015/156] bcm2835-i2s: add 24bit support, update bclk_ratio to
  more correct values
 
 Code ported from bcm2708-i2s driver in Raspberry Pi tree.
diff --git a/target/linux/brcm2708/patches-4.4/0016-bcm2835-i2s-setup-clock-only-if-CPU-is-clock-master.patch b/target/linux/brcm2708/patches-4.4/0016-bcm2835-i2s-setup-clock-only-if-CPU-is-clock-master.patch
index e096656..33746cc 100644
--- a/target/linux/brcm2708/patches-4.4/0016-bcm2835-i2s-setup-clock-only-if-CPU-is-clock-master.patch
+++ b/target/linux/brcm2708/patches-4.4/0016-bcm2835-i2s-setup-clock-only-if-CPU-is-clock-master.patch
@@ -1,7 +1,7 @@
-From fce554c6331b34458db54722cb06eb517a32b305 Mon Sep 17 00:00:00 2001
+From 19ed56e06d7b9342227ccf5942471d3c265a1685 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 15:25:51 +0200
-Subject: [PATCH 016/127] bcm2835-i2s: setup clock only if CPU is clock master
+Subject: [PATCH 016/156] bcm2835-i2s: setup clock only if CPU is clock master
 
 Code ported from bcm2708-i2s driver in Raspberry Pi tree.
 
diff --git a/target/linux/brcm2708/patches-4.4/0017-bcm2835-i2s-Eliminate-debugfs-directory-error.patch b/target/linux/brcm2708/patches-4.4/0017-bcm2835-i2s-Eliminate-debugfs-directory-error.patch
index 1caa347..a7277ce 100644
--- a/target/linux/brcm2708/patches-4.4/0017-bcm2835-i2s-Eliminate-debugfs-directory-error.patch
+++ b/target/linux/brcm2708/patches-4.4/0017-bcm2835-i2s-Eliminate-debugfs-directory-error.patch
@@ -1,7 +1,7 @@
-From 45995262bd8d5194e9430d2a826c84ed28c408eb Mon Sep 17 00:00:00 2001
+From cdc4ea613c38dc44e44dabba95b2eb594c22cd29 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 15:49:51 +0200
-Subject: [PATCH 017/127] bcm2835-i2s: Eliminate debugfs directory error
+Subject: [PATCH 017/156] bcm2835-i2s: Eliminate debugfs directory error
 
 Code ported from bcm2708-i2s driver in Raspberry Pi tree.
 
diff --git a/target/linux/brcm2708/patches-4.4/0018-bcm2835-i2s-Register-PCM-device.patch b/target/linux/brcm2708/patches-4.4/0018-bcm2835-i2s-Register-PCM-device.patch
index eeb7d61..13b6785 100644
--- a/target/linux/brcm2708/patches-4.4/0018-bcm2835-i2s-Register-PCM-device.patch
+++ b/target/linux/brcm2708/patches-4.4/0018-bcm2835-i2s-Register-PCM-device.patch
@@ -1,7 +1,7 @@
-From b58d4ef09eca4674d1530f0c8e1ca074b269ebea Mon Sep 17 00:00:00 2001
+From f74c822d357e64c2da9d116a532bd581522efc06 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 15:35:20 +0200
-Subject: [PATCH 018/127] bcm2835-i2s: Register PCM device
+Subject: [PATCH 018/156] bcm2835-i2s: Register PCM device
 
 Code ported from bcm2708-i2s driver in Raspberry Pi tree.
 
diff --git a/target/linux/brcm2708/patches-4.4/0019-bcm2835-i2s-Enable-MMAP-support-via-a-DT-property.patch b/target/linux/brcm2708/patches-4.4/0019-bcm2835-i2s-Enable-MMAP-support-via-a-DT-property.patch
index c422cc7..4ea245b 100644
--- a/target/linux/brcm2708/patches-4.4/0019-bcm2835-i2s-Enable-MMAP-support-via-a-DT-property.patch
+++ b/target/linux/brcm2708/patches-4.4/0019-bcm2835-i2s-Enable-MMAP-support-via-a-DT-property.patch
@@ -1,7 +1,7 @@
-From 61f155e164c5dbfa5cec9a099e4aa802c2155423 Mon Sep 17 00:00:00 2001
+From 72e07a497854cf8f63ffafc84e016ed859cb7d31 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 15:55:21 +0200
-Subject: [PATCH 019/127] bcm2835-i2s: Enable MMAP support via a DT property
+Subject: [PATCH 019/156] bcm2835-i2s: Enable MMAP support via a DT property
 
 Code ported from bcm2708-i2s driver in Raspberry Pi tree.
 
diff --git a/target/linux/brcm2708/patches-4.4/0020-dmaengine-bcm2835-Add-slave-dma-support.patch b/target/linux/brcm2708/patches-4.4/0020-dmaengine-bcm2835-Add-slave-dma-support.patch
index c49e482..6da23d4 100644
--- a/target/linux/brcm2708/patches-4.4/0020-dmaengine-bcm2835-Add-slave-dma-support.patch
+++ b/target/linux/brcm2708/patches-4.4/0020-dmaengine-bcm2835-Add-slave-dma-support.patch
@@ -1,7 +1,7 @@
-From 780a1039ccfd293d583742a4f2326997b15f5aff Mon Sep 17 00:00:00 2001
+From 79923137826ff02cad3536d7984626065f42ce6d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Thu, 9 Apr 2015 12:34:11 +0200
-Subject: [PATCH 020/127] dmaengine: bcm2835: Add slave dma support
+Subject: [PATCH 020/156] dmaengine: bcm2835: Add slave dma support
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0021-dmaengine-bcm2835-set-residue_granularity-field.patch b/target/linux/brcm2708/patches-4.4/0021-dmaengine-bcm2835-set-residue_granularity-field.patch
index 1e562ce..7b41e92 100644
--- a/target/linux/brcm2708/patches-4.4/0021-dmaengine-bcm2835-set-residue_granularity-field.patch
+++ b/target/linux/brcm2708/patches-4.4/0021-dmaengine-bcm2835-set-residue_granularity-field.patch
@@ -1,7 +1,7 @@
-From 6ff0d626e7d84df71f6bc75e2c5ed35c42858bcc Mon Sep 17 00:00:00 2001
+From b6906312ccc7e18a0d8608c1d1bc318ab6f84656 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Sat, 3 Oct 2015 15:58:59 +0200
-Subject: [PATCH 021/127] dmaengine: bcm2835: set residue_granularity field
+Subject: [PATCH 021/156] dmaengine: bcm2835: set residue_granularity field
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0022-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch b/target/linux/brcm2708/patches-4.4/0022-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch
index e3c9595..59a7d28 100644
--- a/target/linux/brcm2708/patches-4.4/0022-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch
+++ b/target/linux/brcm2708/patches-4.4/0022-dmaengine-bcm2835-Load-driver-early-and-support-lega.patch
@@ -1,7 +1,7 @@
-From 16dc5e0535e48ce3e9c6995c87118e9e7b5b775a Mon Sep 17 00:00:00 2001
+From 53fcf558378cab445edc70a2a03a4ec7e1498107 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Sat, 3 Oct 2015 22:22:55 +0200
-Subject: [PATCH 022/127] dmaengine: bcm2835: Load driver early and support
+Subject: [PATCH 022/156] dmaengine: bcm2835: Load driver early and support
  legacy API
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
diff --git a/target/linux/brcm2708/patches-4.4/0023-bcm2835-dma-Fix-dreq-not-set-for-slave-transfers.patch b/target/linux/brcm2708/patches-4.4/0023-bcm2835-dma-Fix-dreq-not-set-for-slave-transfers.patch
index 42cf9fd..ae6c222 100644
--- a/target/linux/brcm2708/patches-4.4/0023-bcm2835-dma-Fix-dreq-not-set-for-slave-transfers.patch
+++ b/target/linux/brcm2708/patches-4.4/0023-bcm2835-dma-Fix-dreq-not-set-for-slave-transfers.patch
@@ -1,7 +1,7 @@
-From 50eef5c715b894683aebf81332c82426dc10f8cb Mon Sep 17 00:00:00 2001
+From a8f6a0a5ad90dd940fffcd73311abb1aae8acfcc Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sat, 10 Oct 2015 12:29:18 +0200
-Subject: [PATCH 023/127] bcm2835-dma: Fix dreq not set for slave transfers
+Subject: [PATCH 023/156] bcm2835-dma: Fix dreq not set for slave transfers
 
 Set dreq to slave_id if it is not set like in bcm2708-dmaengine.
 ---
diff --git a/target/linux/brcm2708/patches-4.4/0024-bcm2835-dma-Limit-cyclic-transfers-on-lite-channels-.patch b/target/linux/brcm2708/patches-4.4/0024-bcm2835-dma-Limit-cyclic-transfers-on-lite-channels-.patch
index 4461fec..b346571 100644
--- a/target/linux/brcm2708/patches-4.4/0024-bcm2835-dma-Limit-cyclic-transfers-on-lite-channels-.patch
+++ b/target/linux/brcm2708/patches-4.4/0024-bcm2835-dma-Limit-cyclic-transfers-on-lite-channels-.patch
@@ -1,7 +1,7 @@
-From c7e464c38d38ad59899c94dfad6c3455c18f7d76 Mon Sep 17 00:00:00 2001
+From 0ab04f220a909d20f991f3392d65aceb0ec7e774 Mon Sep 17 00:00:00 2001
 From: Matthias Reichl <hias at horus.com>
 Date: Sun, 11 Oct 2015 12:28:30 +0200
-Subject: [PATCH 024/127] bcm2835-dma: Limit cyclic transfers on lite channels
+Subject: [PATCH 024/156] bcm2835-dma: Limit cyclic transfers on lite channels
  to 32k
 
 Transfers larger than 32k cause repeated clicking with I2S soundcards.
diff --git a/target/linux/brcm2708/patches-4.4/0025-bcm2835-Add-support-for-uart1.patch b/target/linux/brcm2708/patches-4.4/0025-bcm2835-Add-support-for-uart1.patch
index cd7f242..1703ac4 100644
--- a/target/linux/brcm2708/patches-4.4/0025-bcm2835-Add-support-for-uart1.patch
+++ b/target/linux/brcm2708/patches-4.4/0025-bcm2835-Add-support-for-uart1.patch
@@ -1,7 +1,7 @@
-From 34cb40cb97cd3080d3d0f314b2b063939b90c069 Mon Sep 17 00:00:00 2001
+From 71b7745f15495d3f9fd59be9e5789c18581d60a0 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Sat, 15 Aug 2015 20:50:02 +0200
-Subject: [PATCH 025/127] bcm2835: Add support for uart1
+Subject: [PATCH 025/156] bcm2835: Add support for uart1
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0026-firmware-bcm2835-Add-missing-property-tags.patch b/target/linux/brcm2708/patches-4.4/0026-firmware-bcm2835-Add-missing-property-tags.patch
index 8bd7be9..1701234 100644
--- a/target/linux/brcm2708/patches-4.4/0026-firmware-bcm2835-Add-missing-property-tags.patch
+++ b/target/linux/brcm2708/patches-4.4/0026-firmware-bcm2835-Add-missing-property-tags.patch
@@ -1,7 +1,7 @@
-From 40946ea47dd52c827b30d3601f7b393c46fbfcf3 Mon Sep 17 00:00:00 2001
+From e289839705c709e9c4479566cef5605466f6a648 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Fri, 26 Jun 2015 14:21:20 +0200
-Subject: [PATCH 026/127] firmware: bcm2835: Add missing property tags
+Subject: [PATCH 026/156] firmware: bcm2835: Add missing property tags
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch b/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch
index 56120c6..7a4c34d 100644
--- a/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch
+++ b/target/linux/brcm2708/patches-4.4/0027-Main-bcm2708-bcm2709-linux-port.patch
@@ -1,7 +1,7 @@
-From 75ae3f717d7598a6eb1582097923ee0838a02a8b Mon Sep 17 00:00:00 2001
+From e6b5eb84f3342be4dd3838279802b43521cd419f Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Sun, 12 May 2013 12:24:19 +0100
-Subject: [PATCH 027/127] Main bcm2708/bcm2709 linux port
+Subject: [PATCH 027/156] Main bcm2708/bcm2709 linux port
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0028-squash-include-ARCH_BCM2708-ARCH_BCM2709.patch b/target/linux/brcm2708/patches-4.4/0028-squash-include-ARCH_BCM2708-ARCH_BCM2709.patch
index 53fc545..707d8ce 100644
--- a/target/linux/brcm2708/patches-4.4/0028-squash-include-ARCH_BCM2708-ARCH_BCM2709.patch
+++ b/target/linux/brcm2708/patches-4.4/0028-squash-include-ARCH_BCM2708-ARCH_BCM2709.patch
@@ -1,7 +1,7 @@
-From ceefa4e6b0d4b529eed6666120674cccde24d59a Mon Sep 17 00:00:00 2001
+From eb50bdd77b032b204591287bd7b5881ab31162a3 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 11 Nov 2015 21:01:15 +0000
-Subject: [PATCH 028/127] squash: include ARCH_BCM2708 / ARCH_BCM2709
+Subject: [PATCH 028/156] squash: include ARCH_BCM2708 / ARCH_BCM2709
 
 ---
  drivers/char/hw_random/Kconfig    |  2 +-
diff --git a/target/linux/brcm2708/patches-4.4/0029-Add-dwc_otg-driver.patch b/target/linux/brcm2708/patches-4.4/0029-Add-dwc_otg-driver.patch
index ee8c4fa..909cffe 100644
--- a/target/linux/brcm2708/patches-4.4/0029-Add-dwc_otg-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0029-Add-dwc_otg-driver.patch
@@ -1,7 +1,7 @@
-From 3fa74ccc327ddeb8f718cf4c42d61b43cc0a9626 Mon Sep 17 00:00:00 2001
+From 9a08cd1f14fd6e6797ddf99303175088bdb0ff90 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 1 May 2013 19:46:17 +0100
-Subject: [PATCH 029/127] Add dwc_otg driver
+Subject: [PATCH 029/156] Add dwc_otg driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0030-bcm2708-framebuffer-driver.patch b/target/linux/brcm2708/patches-4.4/0030-bcm2708-framebuffer-driver.patch
index cfebca2..598cf5f 100644
--- a/target/linux/brcm2708/patches-4.4/0030-bcm2708-framebuffer-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0030-bcm2708-framebuffer-driver.patch
@@ -1,7 +1,7 @@
-From fdf40ab8630e6a5a370b8d938957709f6f8f8324 Mon Sep 17 00:00:00 2001
+From 5722cc32ff8ec100e2f0490d4b94a257085871ff Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 17 Jun 2015 17:06:34 +0100
-Subject: [PATCH 030/127] bcm2708 framebuffer driver
+Subject: [PATCH 030/156] bcm2708 framebuffer driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0031-dmaengine-Add-support-for-BCM2708.patch b/target/linux/brcm2708/patches-4.4/0031-dmaengine-Add-support-for-BCM2708.patch
index 38d70d9..536f77c 100644
--- a/target/linux/brcm2708/patches-4.4/0031-dmaengine-Add-support-for-BCM2708.patch
+++ b/target/linux/brcm2708/patches-4.4/0031-dmaengine-Add-support-for-BCM2708.patch
@@ -1,7 +1,7 @@
-From 51d9f11052d8e51931b1c5f816d737e64e1caa22 Mon Sep 17 00:00:00 2001
+From 04c9e1905ed9aae6208650d81c26baa142fc9e7c Mon Sep 17 00:00:00 2001
 From: Florian Meier <florian.meier at koalo.de>
 Date: Fri, 22 Nov 2013 14:22:53 +0100
-Subject: [PATCH 031/127] dmaengine: Add support for BCM2708
+Subject: [PATCH 031/156] dmaengine: Add support for BCM2708
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0032-Add-blk_pos-parameter-to-mmc-multi_io_quirk-callback.patch b/target/linux/brcm2708/patches-4.4/0032-Add-blk_pos-parameter-to-mmc-multi_io_quirk-callback.patch
index 9e697e8..269a7be 100644
--- a/target/linux/brcm2708/patches-4.4/0032-Add-blk_pos-parameter-to-mmc-multi_io_quirk-callback.patch
+++ b/target/linux/brcm2708/patches-4.4/0032-Add-blk_pos-parameter-to-mmc-multi_io_quirk-callback.patch
@@ -1,7 +1,7 @@
-From 664c65e9a1191f4123b3d88595735d9ab56839e6 Mon Sep 17 00:00:00 2001
+From 8883ad2926f389ee00f33ef52b1a8d7ecdad085f Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Fri, 17 Apr 2015 19:30:22 +0100
-Subject: [PATCH 032/127] Add blk_pos parameter to mmc multi_io_quirk callback
+Subject: [PATCH 032/156] Add blk_pos parameter to mmc multi_io_quirk callback
 
 ---
  drivers/mmc/card/block.c          | 1 +
diff --git a/target/linux/brcm2708/patches-4.4/0033-MMC-added-alternative-MMC-driver.patch b/target/linux/brcm2708/patches-4.4/0033-MMC-added-alternative-MMC-driver.patch
index c0ae1a2..e42602c 100644
--- a/target/linux/brcm2708/patches-4.4/0033-MMC-added-alternative-MMC-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0033-MMC-added-alternative-MMC-driver.patch
@@ -1,7 +1,7 @@
-From d44fe69d1a40ccd48ca963476ae6a1d4378349fd Mon Sep 17 00:00:00 2001
+From 118e1dbbd1a750304eaf53ed97f05ee86e6f4d52 Mon Sep 17 00:00:00 2001
 From: gellert <gellert at raspberrypi.org>
 Date: Fri, 15 Aug 2014 16:35:06 +0100
-Subject: [PATCH 033/127] MMC: added alternative MMC driver
+Subject: [PATCH 033/156] MMC: added alternative MMC driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0034-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch b/target/linux/brcm2708/patches-4.4/0034-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
index c53bea3..4e4a548 100644
--- a/target/linux/brcm2708/patches-4.4/0034-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
+++ b/target/linux/brcm2708/patches-4.4/0034-Adding-bcm2835-sdhost-driver-and-an-overlay-to-enabl.patch
@@ -1,7 +1,7 @@
-From 9fccc853c4977f9a125de717e7eee0f25895362e Mon Sep 17 00:00:00 2001
+From d29928fd47f28cf8ee0221c4979da984203503a1 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Wed, 25 Mar 2015 17:49:47 +0000
-Subject: [PATCH 034/127] Adding bcm2835-sdhost driver, and an overlay to
+Subject: [PATCH 034/156] Adding bcm2835-sdhost driver, and an overlay to
  enable it
 
 BCM2835 has two SD card interfaces. This driver uses the other one.
diff --git a/target/linux/brcm2708/patches-4.4/0035-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch b/target/linux/brcm2708/patches-4.4/0035-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
index f41db1a..b825c7a 100644
--- a/target/linux/brcm2708/patches-4.4/0035-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
+++ b/target/linux/brcm2708/patches-4.4/0035-cma-Add-vc_cma-driver-to-enable-use-of-CMA.patch
@@ -1,7 +1,7 @@
-From 596a45736af7c7721bd7b8a9cbd04cbcd6c11b53 Mon Sep 17 00:00:00 2001
+From c6f15fd48c94d179e6e829cee2c36c2b4dc9a07d Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 3 Jul 2013 00:31:47 +0100
-Subject: [PATCH 035/127] cma: Add vc_cma driver to enable use of CMA
+Subject: [PATCH 035/156] cma: Add vc_cma driver to enable use of CMA
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0036-bcm2708-alsa-sound-driver.patch b/target/linux/brcm2708/patches-4.4/0036-bcm2708-alsa-sound-driver.patch
index 47cb912..57d4ba0 100644
--- a/target/linux/brcm2708/patches-4.4/0036-bcm2708-alsa-sound-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0036-bcm2708-alsa-sound-driver.patch
@@ -1,7 +1,7 @@
-From d3e64892070a0399dad4cdae9e72bb9c7801b86d Mon Sep 17 00:00:00 2001
+From 26d9897700046c008240842bafec44eed727df89 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Mon, 26 Mar 2012 22:15:50 +0100
-Subject: [PATCH 036/127] bcm2708: alsa sound driver
+Subject: [PATCH 036/156] bcm2708: alsa sound driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0037-bcm2708-vchiq-driver.patch b/target/linux/brcm2708/patches-4.4/0037-bcm2708-vchiq-driver.patch
index b2c3ee0..554fdc7 100644
--- a/target/linux/brcm2708/patches-4.4/0037-bcm2708-vchiq-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0037-bcm2708-vchiq-driver.patch
@@ -1,7 +1,7 @@
-From 01551caa3e4d71d3a75703b063a871f18541f38d Mon Sep 17 00:00:00 2001
+From ad0b56e0e4c45cbc6014f6befcb53ffc05dff857 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Tue, 2 Jul 2013 23:42:01 +0100
-Subject: [PATCH 037/127] bcm2708 vchiq driver
+Subject: [PATCH 037/156] bcm2708 vchiq driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0038-vc_mem-Add-vc_mem-driver.patch b/target/linux/brcm2708/patches-4.4/0038-vc_mem-Add-vc_mem-driver.patch
index f7cc213..3a02267 100644
--- a/target/linux/brcm2708/patches-4.4/0038-vc_mem-Add-vc_mem-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0038-vc_mem-Add-vc_mem-driver.patch
@@ -1,7 +1,7 @@
-From bb0a865b1cbbb1dd887378111af03727884e3476 Mon Sep 17 00:00:00 2001
+From 431b30a19d76bc784aa609481c43121092b81f86 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 17 Jun 2015 16:07:06 +0100
-Subject: [PATCH 038/127] vc_mem: Add vc_mem driver
+Subject: [PATCH 038/156] vc_mem: Add vc_mem driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0039-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch b/target/linux/brcm2708/patches-4.4/0039-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
index a67c9b2..2298b68 100644
--- a/target/linux/brcm2708/patches-4.4/0039-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
+++ b/target/linux/brcm2708/patches-4.4/0039-vcsm-VideoCore-shared-memory-service-for-BCM2835.patch
@@ -1,7 +1,7 @@
-From 40793263e733bd6fa4b2a063891661ae59076430 Mon Sep 17 00:00:00 2001
+From d70f57c3da95fc54dfd702cb3d521cc3a9cc9850 Mon Sep 17 00:00:00 2001
 From: Tim Gover <tgover at broadcom.com>
 Date: Tue, 22 Jul 2014 15:41:04 +0100
-Subject: [PATCH 039/127] vcsm: VideoCore shared memory service for BCM2835
+Subject: [PATCH 039/156] vcsm: VideoCore shared memory service for BCM2835
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0040-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch b/target/linux/brcm2708/patches-4.4/0040-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
index cf964e1..240aab9 100644
--- a/target/linux/brcm2708/patches-4.4/0040-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
+++ b/target/linux/brcm2708/patches-4.4/0040-Add-dev-gpiomem-device-for-rootless-user-GPIO-access.patch
@@ -1,7 +1,7 @@
-From 6ddd3a6f0a8a3e4506b4fe4e1b410d9d945c5df2 Mon Sep 17 00:00:00 2001
+From a582dfc468cbb9176054bdcc02dce40a0e0441e6 Mon Sep 17 00:00:00 2001
 From: Luke Wren <luke at raspberrypi.org>
 Date: Fri, 21 Aug 2015 23:14:48 +0100
-Subject: [PATCH 040/127] Add /dev/gpiomem device for rootless user GPIO access
+Subject: [PATCH 040/156] Add /dev/gpiomem device for rootless user GPIO access
 
 Signed-off-by: Luke Wren <luke at raspberrypi.org>
 
diff --git a/target/linux/brcm2708/patches-4.4/0041-Add-SMI-driver.patch b/target/linux/brcm2708/patches-4.4/0041-Add-SMI-driver.patch
index 7075ddb..a0da87a 100644
--- a/target/linux/brcm2708/patches-4.4/0041-Add-SMI-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0041-Add-SMI-driver.patch
@@ -1,7 +1,7 @@
-From 9e50bbd976d3c77770fe98e7e1465012aa2d19d4 Mon Sep 17 00:00:00 2001
+From 7ccd5e32f6e98f1522a3e471e4afeef564497264 Mon Sep 17 00:00:00 2001
 From: Luke Wren <wren6991 at gmail.com>
 Date: Sat, 5 Sep 2015 01:14:45 +0100
-Subject: [PATCH 041/127] Add SMI driver
+Subject: [PATCH 041/156] Add SMI driver
 
 Signed-off-by: Luke Wren <wren6991 at gmail.com>
 ---
diff --git a/target/linux/brcm2708/patches-4.4/0042-Add-SMI-NAND-driver.patch b/target/linux/brcm2708/patches-4.4/0042-Add-SMI-NAND-driver.patch
index 091e333..2807310 100644
--- a/target/linux/brcm2708/patches-4.4/0042-Add-SMI-NAND-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0042-Add-SMI-NAND-driver.patch
@@ -1,7 +1,7 @@
-From 142af590ca0a7fc36905f5bd123103c730d22a07 Mon Sep 17 00:00:00 2001
+From 06301e219cb176ca2917ad7e51fc9cf9897cf52b Mon Sep 17 00:00:00 2001
 From: Luke Wren <wren6991 at gmail.com>
 Date: Sat, 5 Sep 2015 01:16:10 +0100
-Subject: [PATCH 042/127] Add SMI NAND driver
+Subject: [PATCH 042/156] Add SMI NAND driver
 
 Signed-off-by: Luke Wren <wren6991 at gmail.com>
 ---
diff --git a/target/linux/brcm2708/patches-4.4/0043-lirc-added-support-for-RaspberryPi-GPIO.patch b/target/linux/brcm2708/patches-4.4/0043-lirc-added-support-for-RaspberryPi-GPIO.patch
index 728ac37..466bea3 100644
--- a/target/linux/brcm2708/patches-4.4/0043-lirc-added-support-for-RaspberryPi-GPIO.patch
+++ b/target/linux/brcm2708/patches-4.4/0043-lirc-added-support-for-RaspberryPi-GPIO.patch
@@ -1,7 +1,7 @@
-From b9a3e6cbf575d0463af4b47ce48f76624bae10a1 Mon Sep 17 00:00:00 2001
+From 38d02987b33c187e2a02794c0b97c28d270f1d9b Mon Sep 17 00:00:00 2001
 From: Aron Szabo <aron at aron.ws>
 Date: Sat, 16 Jun 2012 12:15:55 +0200
-Subject: [PATCH 043/127] lirc: added support for RaspberryPi GPIO
+Subject: [PATCH 043/156] lirc: added support for RaspberryPi GPIO
 
 lirc_rpi: Use read_current_timer to determine transmitter delay. Thanks to jjmz and others
 See: https://github.com/raspberrypi/linux/issues/525
diff --git a/target/linux/brcm2708/patches-4.4/0044-Add-cpufreq-driver.patch b/target/linux/brcm2708/patches-4.4/0044-Add-cpufreq-driver.patch
index 00be38f..3d48bf9 100644
--- a/target/linux/brcm2708/patches-4.4/0044-Add-cpufreq-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0044-Add-cpufreq-driver.patch
@@ -1,7 +1,7 @@
-From 21e72e1f417fe2c097fe8f8ba4963abdde88a6ca Mon Sep 17 00:00:00 2001
+From c2a1eecef94520be7c785cf6d23aca9c695122f5 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 3 Jul 2013 00:49:20 +0100
-Subject: [PATCH 044/127] Add cpufreq driver
+Subject: [PATCH 044/156] Add cpufreq driver
 
 Signed-off-by: popcornmix <popcornmix at gmail.com>
 ---
diff --git a/target/linux/brcm2708/patches-4.4/0045-Added-hwmon-thermal-driver-for-reporting-core-temper.patch b/target/linux/brcm2708/patches-4.4/0045-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
index bcb7550..72af401 100644
--- a/target/linux/brcm2708/patches-4.4/0045-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
+++ b/target/linux/brcm2708/patches-4.4/0045-Added-hwmon-thermal-driver-for-reporting-core-temper.patch
@@ -1,7 +1,7 @@
-From ffe7f669c4106fafe86597774697048258cedbc9 Mon Sep 17 00:00:00 2001
+From 76ad29cef7e6dc73d7f9c3cd3578783d1daefa6d Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Tue, 26 Mar 2013 19:24:24 +0000
-Subject: [PATCH 045/127] Added hwmon/thermal driver for reporting core
+Subject: [PATCH 045/156] Added hwmon/thermal driver for reporting core
  temperature. Thanks Dorian
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
diff --git a/target/linux/brcm2708/patches-4.4/0046-Add-Chris-Boot-s-i2c-driver.patch b/target/linux/brcm2708/patches-4.4/0046-Add-Chris-Boot-s-i2c-driver.patch
index c3e8b0c..dec288d 100644
--- a/target/linux/brcm2708/patches-4.4/0046-Add-Chris-Boot-s-i2c-driver.patch
+++ b/target/linux/brcm2708/patches-4.4/0046-Add-Chris-Boot-s-i2c-driver.patch
@@ -1,7 +1,7 @@
-From 052aa5593d1cd52bbabc0985e9630f8272f3226a Mon Sep 17 00:00:00 2001
+From aac476eac7be9830cbda14fe82afa7d4afbd41d2 Mon Sep 17 00:00:00 2001
 From: popcornmix <popcornmix at gmail.com>
 Date: Wed, 17 Jun 2015 15:44:08 +0100
-Subject: [PATCH 046/127] Add Chris Boot's i2c driver
+Subject: [PATCH 046/156] Add Chris Boot's i2c driver
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0047-char-broadcom-Add-vcio-module.patch b/target/linux/brcm2708/patches-4.4/0047-char-broadcom-Add-vcio-module.patch
index b9a5c24..74b4303 100644
--- a/target/linux/brcm2708/patches-4.4/0047-char-broadcom-Add-vcio-module.patch
+++ b/target/linux/brcm2708/patches-4.4/0047-char-broadcom-Add-vcio-module.patch
@@ -1,7 +1,7 @@
-From 18ec30d7e1571af21c41b687bd12e22f05ffd0b2 Mon Sep 17 00:00:00 2001
+From 8e1245bf1c5553baec76ccb0deb521df84a3f48f Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Fri, 26 Jun 2015 14:27:06 +0200
-Subject: [PATCH 047/127] char: broadcom: Add vcio module
+Subject: [PATCH 047/156] char: broadcom: Add vcio module
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0048-firmware-bcm2835-Support-ARCH_BCM270x.patch b/target/linux/brcm2708/patches-4.4/0048-firmware-bcm2835-Support-ARCH_BCM270x.patch
index 78e8605..e574082 100644
--- a/target/linux/brcm2708/patches-4.4/0048-firmware-bcm2835-Support-ARCH_BCM270x.patch
+++ b/target/linux/brcm2708/patches-4.4/0048-firmware-bcm2835-Support-ARCH_BCM270x.patch
@@ -1,7 +1,7 @@
-From 1d1c3e9b18717f6510b67c582e93051a3a948eb6 Mon Sep 17 00:00:00 2001
+From bf182799da48b6072c783fed452a752715b9b479 Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Fri, 26 Jun 2015 14:25:01 +0200
-Subject: [PATCH 048/127] firmware: bcm2835: Support ARCH_BCM270x
+Subject: [PATCH 048/156] firmware: bcm2835: Support ARCH_BCM270x
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0049-bcm2835-add-v4l2-camera-device.patch b/target/linux/brcm2708/patches-4.4/0049-bcm2835-add-v4l2-camera-device.patch
index b9f1746..ca6ddeb 100644
--- a/target/linux/brcm2708/patches-4.4/0049-bcm2835-add-v4l2-camera-device.patch
+++ b/target/linux/brcm2708/patches-4.4/0049-bcm2835-add-v4l2-camera-device.patch
@@ -1,7 +1,7 @@
-From 1e7cf5d5acfaecbc92766c179dba544064fb94cc Mon Sep 17 00:00:00 2001
+From f4ccd72c0038efded59351ceb59dc0a1f227890c Mon Sep 17 00:00:00 2001
 From: Vincent Sanders <vincent.sanders at collabora.co.uk>
 Date: Wed, 30 Jan 2013 12:45:18 +0000
-Subject: [PATCH 049/127] bcm2835: add v4l2 camera device
+Subject: [PATCH 049/156] bcm2835: add v4l2 camera device
 
 - Supports raw YUV capture, preview, JPEG and H264.
 - Uses videobuf2 for data transfer, using dma_buf.
diff --git a/target/linux/brcm2708/patches-4.4/0050-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch b/target/linux/brcm2708/patches-4.4/0050-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
index 93c267c..a73ed2b 100644
--- a/target/linux/brcm2708/patches-4.4/0050-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
+++ b/target/linux/brcm2708/patches-4.4/0050-scripts-Add-mkknlimg-and-knlinfo-scripts-from-tools-.patch
@@ -1,7 +1,7 @@
-From 4ddb3fae0a5c5b6969168134b4352bceccf51b9c Mon Sep 17 00:00:00 2001
+From a98c2f7958c16abd5d1536f80c241ec83ee99b86 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Mon, 11 May 2015 09:00:42 +0100
-Subject: [PATCH 050/127] scripts: Add mkknlimg and knlinfo scripts from tools
+Subject: [PATCH 050/156] scripts: Add mkknlimg and knlinfo scripts from tools
  repo
 
 The Raspberry Pi firmware looks for a trailer on the kernel image to
diff --git a/target/linux/brcm2708/patches-4.4/0051-fdt-Add-support-for-the-CONFIG_CMDLINE_EXTEND-option.patch b/target/linux/brcm2708/patches-4.4/0051-fdt-Add-support-for-the-CONFIG_CMDLINE_EXTEND-option.patch
index c909369..662834d 100644
--- a/target/linux/brcm2708/patches-4.4/0051-fdt-Add-support-for-the-CONFIG_CMDLINE_EXTEND-option.patch
+++ b/target/linux/brcm2708/patches-4.4/0051-fdt-Add-support-for-the-CONFIG_CMDLINE_EXTEND-option.patch
@@ -1,7 +1,7 @@
-From 3f46d3627061688e50e24d5bfbc0adb5deb89b97 Mon Sep 17 00:00:00 2001
+From eafa669fc02f9d7aa9d6fb0376558217d5d432e1 Mon Sep 17 00:00:00 2001
 From: Phil Elwell <phil at raspberrypi.org>
 Date: Fri, 5 Dec 2014 17:26:26 +0000
-Subject: [PATCH 051/127] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
+Subject: [PATCH 051/156] fdt: Add support for the CONFIG_CMDLINE_EXTEND option
 
 ---
  drivers/of/fdt.c | 29 ++++++++++++++++++++++++-----
diff --git a/target/linux/brcm2708/patches-4.4/0052-BCM2708-Add-core-Device-Tree-support.patch b/target/linux/brcm2708/patches-4.4/0052-BCM2708-Add-core-Device-Tree-support.patch
index 52bc6bd..12e7b86 100644
--- a/target/linux/brcm2708/patches-4.4/0052-BCM2708-Add-core-Device-Tree-support.patch
+++ b/target/linux/brcm2708/patches-4.4/0052-BCM2708-Add-core-Device-Tree-support.patch
@@ -1,7 +1,7 @@
-From 46e100d54a3bef01345aaffd1d722f6d2087a170 Mon Sep 17 00:00:00 2001
+From 1bf87715f0e3eb28ca753ec6cc4d189e8bc0de66 Mon Sep 17 00:00:00 2001
 From: notro <notro at tronnes.org>
 Date: Wed, 9 Jul 2014 14:46:08 +0200
-Subject: [PATCH 052/127] BCM2708: Add core Device Tree support
+Subject: [PATCH 052/156] BCM2708: Add core Device Tree support
 
 Add the bare minimum needed to boot BCM2708 from a Device Tree.
 
diff --git a/target/linux/brcm2708/patches-4.4/0053-bcm2835-Match-with-BCM2708-Device-Trees.patch b/target/linux/brcm2708/patches-4.4/0053-bcm2835-Match-with-BCM2708-Device-Trees.patch
index 6105e46..25e0c6b 100644
--- a/target/linux/brcm2708/patches-4.4/0053-bcm2835-Match-with-BCM2708-Device-Trees.patch
+++ b/target/linux/brcm2708/patches-4.4/0053-bcm2835-Match-with-BCM2708-Device-Trees.patch
@@ -1,7 +1,7 @@
-From 1cb8b3610957f9c892a7eb6e18b99eca0ac7a77d Mon Sep 17 00:00:00 2001
+From 3ee2870ef7f0aa7c48a7cd1ae532aa9e1ac4f6ce Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf at tronnes.org>
 Date: Sat, 15 Aug 2015 20:47:07 +0200
-Subject: [PATCH 053/127] bcm2835: Match with BCM2708 Device Trees
+Subject: [PATCH 053/156] bcm2835: Match with BCM2708 Device Trees
 MIME-Version: 1.0
 Content-Type: text/plain; charset=UTF-8
 Content-Transfer-Encoding: 8bit
diff --git a/target/linux/brcm2708/patches-4.4/0054-fbdev-add-FBIOCOPYAREA-ioctl.patch b/target/linux/brcm2708/patches-4.4/0054-fbdev-add-FBIOCOPYAREA-ioctl.patch
index 151b5cf..6f6ebb5 100644
--- a/target/linux/brcm2708/patches-4.4/0054-fbdev-add-FBIOCOPYAREA-ioctl.patch
+++ b/target/linux/brcm2708/patches-4.4/0054-fbdev-add-FBIOCOPYAREA-ioctl.patch
@@ -1,7 +1,7 @@
-From 6faba148320fb8fc49b5cf5e5ef7864d9a1c0fd9 Mon Sep 17 00:00:00 2001
+From 1d6ca03eff36dc3d5675554fb1cb4db6ebeb7e74 Mon Sep 17 00:00:00 2001
 From: Siarhei Siamashka <siarhei.siamashka at gmail.com>
 Date: Mon, 17 Jun 2013 13:32:11 +0300
-Subject: [PATCH 054/127] fbdev: add FBIOCOPYAREA ioctl
+Subject: [PATCH 054/156] fbdev: add FBIOCOPYAREA ioctl
 
 Based on the patch authored by Ali Gholami Rudi at
     https://lkml.org/lkml/2009/7/13/153
diff --git a/target/linux/brcm2708/patches-4.4/0055-Add-non-mainline-source-for-rtl8192cu-wireless-drive.patch b/target/linux/brcm2708/patches-4.4/0055-Add-non-mainline-source-for-rtl8192cu-wireless-drive.patch
new file mode 100644
index 0000000..b9a8961
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.4/0055-Add-non-mainline-source-for-rtl8192cu-wireless-drive.patch
@@ -0,0 +1,172140 @@
+From 532cb6348106fb12aa40e2bee79ef0aa10754618 Mon Sep 17 00:00:00 2001
+From: popcornmix <popcornmix at gmail.com>
+Date: Mon, 3 Sep 2012 17:10:23 +0100
+Subject: [PATCH 055/156] Add non-mainline source for rtl8192cu wireless driver
+ version v4.0.2_9000 as this is widely used. Disabled older rtlwifi driver
+
+8192cu needs old wireless extensions
+
+The obsolete WIRELESS_EXT configuration is used
+by the old Realtek code and is needed for AP support.
+
+8192cu: CONFIG_AP_MODE hardcoded in autoconf.h
+---
+ drivers/net/wireless/Kconfig                       |     3 +-
+ drivers/net/wireless/realtek/Makefile              |     3 +-
+ drivers/net/wireless/realtek/rtl8192cu/Kconfig     |     9 +
+ drivers/net/wireless/realtek/rtl8192cu/Makefile    |   615 +
+ drivers/net/wireless/realtek/rtl8192cu/clean       |     5 +
+ .../realtek/rtl8192cu/core/efuse/rtw_efuse.c       |  1145 ++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_ap.c   |  2939 ++++
+ .../wireless/realtek/rtl8192cu/core/rtw_br_ext.c   |  1699 +++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_cmd.c  |  3034 +++++
+ .../wireless/realtek/rtl8192cu/core/rtw_debug.c    |  1336 ++
+ .../wireless/realtek/rtl8192cu/core/rtw_eeprom.c   |   422 +
+ .../realtek/rtl8192cu/core/rtw_ieee80211.c         |  1914 +++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_io.c   |   462 +
+ .../realtek/rtl8192cu/core/rtw_ioctl_query.c       |   195 +
+ .../realtek/rtl8192cu/core/rtw_ioctl_rtl.c         |  1031 ++
+ .../realtek/rtl8192cu/core/rtw_ioctl_set.c         |  1493 ++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_iol.c  |   262 +
+ .../net/wireless/realtek/rtl8192cu/core/rtw_mlme.c |  3966 ++++++
+ .../wireless/realtek/rtl8192cu/core/rtw_mlme_ext.c | 13599 +++++++++++++++++++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_mp.c   |  1323 ++
+ .../wireless/realtek/rtl8192cu/core/rtw_mp_ioctl.c |  2953 ++++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_p2p.c  |  5293 ++++++++
+ .../wireless/realtek/rtl8192cu/core/rtw_pwrctrl.c  |  1538 +++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_recv.c |  4286 ++++++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_rf.c   |    94 +
+ .../wireless/realtek/rtl8192cu/core/rtw_security.c |  3114 +++++
+ .../wireless/realtek/rtl8192cu/core/rtw_sreset.c   |   351 +
+ .../wireless/realtek/rtl8192cu/core/rtw_sta_mgt.c  |   847 ++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_tdls.c |  2940 ++++
+ .../realtek/rtl8192cu/core/rtw_wlan_util.c         |  2304 ++++
+ .../net/wireless/realtek/rtl8192cu/core/rtw_xmit.c |  4155 ++++++
+ .../wireless/realtek/rtl8192cu/hal/HalPwrSeqCmd.c  |   175 +
+ drivers/net/wireless/realtek/rtl8192cu/hal/dm.c    |   313 +
+ drivers/net/wireless/realtek/rtl8192cu/hal/dm.h    |    30 +
+ .../net/wireless/realtek/rtl8192cu/hal/hal_com.c   |   370 +
+ .../net/wireless/realtek/rtl8192cu/hal/hal_intf.c  |   545 +
+ .../realtek/rtl8192cu/hal/rtl8192c/rtl8192c_cmd.c  |  1154 ++
+ .../realtek/rtl8192cu/hal/rtl8192c/rtl8192c_dm.c   |  5055 +++++++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_hal_init.c     |  3627 +++++
+ .../realtek/rtl8192cu/hal/rtl8192c/rtl8192c_mp.c   |  1207 ++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_phycfg.c       |  4840 +++++++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c       |  1030 ++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_rxdesc.c       |   874 ++
+ .../rtl8192cu/hal/rtl8192c/rtl8192c_sreset.c       |    93 +
+ .../realtek/rtl8192cu/hal/rtl8192c/rtl8192c_xmit.c |    62 +
+ .../rtl8192cu/hal/rtl8192c/usb/Hal8192CUHWImg.c    |  8757 ++++++++++++
+ .../hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c       |  2557 ++++
+ .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_led.c     |  2674 ++++
+ .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_recv.c    |   227 +
+ .../rtl8192cu/hal/rtl8192c/usb/rtl8192cu_xmit.c    |  1149 ++
+ .../rtl8192cu/hal/rtl8192c/usb/usb_halinit.c       |  6260 +++++++++
+ .../rtl8192cu/hal/rtl8192c/usb/usb_ops_ce.c        |  1205 ++
+ .../rtl8192cu/hal/rtl8192c/usb/usb_ops_linux.c     |  1535 +++
+ .../rtl8192cu/hal/rtl8192c/usb/usb_ops_xp.c        |  1264 ++
+ drivers/net/wireless/realtek/rtl8192cu/ifcfg-wlan0 |     4 +
+ .../realtek/rtl8192cu/include/Hal8192CEHWImg.h     |    85 +
+ .../realtek/rtl8192cu/include/Hal8192CPhyCfg.h     |   427 +
+ .../realtek/rtl8192cu/include/Hal8192CPhyReg.h     |  1122 ++
+ .../realtek/rtl8192cu/include/Hal8192CUHWImg.h     |   105 +
+ .../rtl8192cu/include/Hal8192CUHWImg_wowlan.h      |    33 +
+ .../realtek/rtl8192cu/include/Hal8192DEHWImg.h     |    66 +
+ .../realtek/rtl8192cu/include/Hal8192DPhyCfg.h     |   527 +
+ .../realtek/rtl8192cu/include/Hal8192DPhyReg.h     |  1170 ++
+ .../realtek/rtl8192cu/include/Hal8192DUHWImg.h     |    66 +
+ .../rtl8192cu/include/Hal8192DUHWImg_wowlan.h      |    29 +
+ .../realtek/rtl8192cu/include/HalPwrSeqCmd.h       |   137 +
+ .../wireless/realtek/rtl8192cu/include/autoconf.h  |   336 +
+ .../realtek/rtl8192cu/include/basic_types.h        |   320 +
+ .../rtl8192cu/include/byteorder/big_endian.h       |    87 +
+ .../realtek/rtl8192cu/include/byteorder/generic.h  |   212 +
+ .../rtl8192cu/include/byteorder/little_endian.h    |    89 +
+ .../realtek/rtl8192cu/include/byteorder/swab.h     |   140 +
+ .../realtek/rtl8192cu/include/byteorder/swabb.h    |   156 +
+ .../wireless/realtek/rtl8192cu/include/circ_buf.h  |    27 +
+ .../wireless/realtek/rtl8192cu/include/cmd_osdep.h |    35 +
+ .../wireless/realtek/rtl8192cu/include/drv_conf.h  |    77 +
+ .../wireless/realtek/rtl8192cu/include/drv_types.h |   661 +
+ .../realtek/rtl8192cu/include/drv_types_ce.h       |    92 +
+ .../realtek/rtl8192cu/include/drv_types_linux.h    |    24 +
+ .../realtek/rtl8192cu/include/drv_types_sdio.h     |    69 +
+ .../realtek/rtl8192cu/include/drv_types_xp.h       |    94 +
+ .../wireless/realtek/rtl8192cu/include/ethernet.h  |    41 +
+ .../wireless/realtek/rtl8192cu/include/h2clbk.h    |    35 +
+ .../wireless/realtek/rtl8192cu/include/hal_com.h   |   145 +
+ .../wireless/realtek/rtl8192cu/include/hal_intf.h  |   431 +
+ .../wireless/realtek/rtl8192cu/include/ieee80211.h |  1579 +++
+ .../realtek/rtl8192cu/include/ieee80211_ext.h      |   476 +
+ .../wireless/realtek/rtl8192cu/include/if_ether.h  |   112 +
+ .../realtek/rtl8192cu/include/ioctl_cfg80211.h     |   179 +
+ .../net/wireless/realtek/rtl8192cu/include/ip.h    |   141 +
+ .../realtek/rtl8192cu/include/linux/wireless.h     |    90 +
+ .../realtek/rtl8192cu/include/mlme_osdep.h         |    39 +
+ .../realtek/rtl8192cu/include/mp_custom_oid.h      |   353 +
+ .../wireless/realtek/rtl8192cu/include/nic_spec.h  |    46 +
+ .../realtek/rtl8192cu/include/osdep_ce_service.h   |   170 +
+ .../realtek/rtl8192cu/include/osdep_intf.h         |   154 +
+ .../realtek/rtl8192cu/include/osdep_service.h      |  1813 +++
+ .../wireless/realtek/rtl8192cu/include/pci_hal.h   |   167 +
+ .../wireless/realtek/rtl8192cu/include/pci_ops.h   |    60 +
+ .../realtek/rtl8192cu/include/pci_osintf.h         |    32 +
+ .../realtek/rtl8192cu/include/recv_osdep.h         |    57 +
+ .../realtek/rtl8192cu/include/rtl8192c_cmd.h       |   152 +
+ .../realtek/rtl8192cu/include/rtl8192c_dm.h        |   515 +
+ .../realtek/rtl8192cu/include/rtl8192c_event.h     |    26 +
+ .../realtek/rtl8192cu/include/rtl8192c_hal.h       |   934 ++
+ .../realtek/rtl8192cu/include/rtl8192c_led.h       |    41 +
+ .../realtek/rtl8192cu/include/rtl8192c_recv.h      |   183 +
+ .../realtek/rtl8192cu/include/rtl8192c_rf.h        |    91 +
+ .../realtek/rtl8192cu/include/rtl8192c_spec.h      |  1864 +++
+ .../realtek/rtl8192cu/include/rtl8192c_sreset.h    |    32 +
+ .../realtek/rtl8192cu/include/rtl8192c_xmit.h      |   128 +
+ .../realtek/rtl8192cu/include/rtl8192d_cmd.h       |   140 +
+ .../realtek/rtl8192cu/include/rtl8192d_dm.h        |   420 +
+ .../realtek/rtl8192cu/include/rtl8192d_hal.h       |  1125 ++
+ .../realtek/rtl8192cu/include/rtl8192d_led.h       |    42 +
+ .../realtek/rtl8192cu/include/rtl8192d_recv.h      |   186 +
+ .../realtek/rtl8192cu/include/rtl8192d_rf.h        |    96 +
+ .../realtek/rtl8192cu/include/rtl8192d_spec.h      |  1840 +++
+ .../realtek/rtl8192cu/include/rtl8192d_xmit.h      |   144 +
+ .../realtek/rtl8192cu/include/rtw_android.h        |    89 +
+ .../wireless/realtek/rtl8192cu/include/rtw_ap.h    |    63 +
+ .../realtek/rtl8192cu/include/rtw_br_ext.h         |    75 +
+ .../realtek/rtl8192cu/include/rtw_byteorder.h      |    39 +
+ .../wireless/realtek/rtl8192cu/include/rtw_cmd.h   |  1166 ++
+ .../wireless/realtek/rtl8192cu/include/rtw_debug.h |   537 +
+ .../realtek/rtl8192cu/include/rtw_eeprom.h         |   152 +
+ .../wireless/realtek/rtl8192cu/include/rtw_efuse.h |   123 +
+ .../wireless/realtek/rtl8192cu/include/rtw_event.h |   153 +
+ .../wireless/realtek/rtl8192cu/include/rtw_ht.h    |    49 +
+ .../wireless/realtek/rtl8192cu/include/rtw_io.h    |   504 +
+ .../wireless/realtek/rtl8192cu/include/rtw_ioctl.h |   268 +
+ .../realtek/rtl8192cu/include/rtw_ioctl_query.h    |    35 +
+ .../realtek/rtl8192cu/include/rtw_ioctl_rtl.h      |    83 +
+ .../realtek/rtl8192cu/include/rtw_ioctl_set.h      |    78 +
+ .../wireless/realtek/rtl8192cu/include/rtw_iol.h   |    89 +
+ .../wireless/realtek/rtl8192cu/include/rtw_led.h   |   216 +
+ .../wireless/realtek/rtl8192cu/include/rtw_mlme.h  |   843 ++
+ .../realtek/rtl8192cu/include/rtw_mlme_ext.h       |   962 ++
+ .../wireless/realtek/rtl8192cu/include/rtw_mp.h    |   711 +
+ .../realtek/rtl8192cu/include/rtw_mp_ioctl.h       |   595 +
+ .../realtek/rtl8192cu/include/rtw_mp_phy_regdef.h  |  1096 ++
+ .../wireless/realtek/rtl8192cu/include/rtw_p2p.h   |   160 +
+ .../realtek/rtl8192cu/include/rtw_pwrctrl.h        |   362 +
+ .../wireless/realtek/rtl8192cu/include/rtw_qos.h   |    39 +
+ .../wireless/realtek/rtl8192cu/include/rtw_recv.h  |   730 +
+ .../wireless/realtek/rtl8192cu/include/rtw_rf.h    |   151 +
+ .../realtek/rtl8192cu/include/rtw_security.h       |   446 +
+ .../realtek/rtl8192cu/include/rtw_sreset.h         |    73 +
+ .../wireless/realtek/rtl8192cu/include/rtw_tdls.h  |   142 +
+ .../realtek/rtl8192cu/include/rtw_version.h        |     1 +
+ .../wireless/realtek/rtl8192cu/include/rtw_xmit.h  |   753 +
+ .../wireless/realtek/rtl8192cu/include/sta_info.h  |   431 +
+ .../wireless/realtek/rtl8192cu/include/usb_hal.h   |    36 +
+ .../wireless/realtek/rtl8192cu/include/usb_ops.h   |   109 +
+ .../realtek/rtl8192cu/include/usb_ops_linux.h      |    62 +
+ .../realtek/rtl8192cu/include/usb_osintf.h         |    37 +
+ .../realtek/rtl8192cu/include/usb_vendor_req.h     |    59 +
+ .../net/wireless/realtek/rtl8192cu/include/wifi.h  |  1245 ++
+ .../realtek/rtl8192cu/include/wlan_bssdef.h        |   702 +
+ .../realtek/rtl8192cu/include/xmit_osdep.h         |    94 +
+ .../rtl8192cu/os_dep/linux/ioctl_cfg80211.c        |  5488 ++++++++
+ .../realtek/rtl8192cu/os_dep/linux/ioctl_linux.c   | 11908 ++++++++++++++++
+ .../realtek/rtl8192cu/os_dep/linux/mlme_linux.c    |   585 +
+ .../realtek/rtl8192cu/os_dep/linux/os_intfs.c      |  2748 ++++
+ .../realtek/rtl8192cu/os_dep/linux/pci_intf.c      |  1996 +++
+ .../realtek/rtl8192cu/os_dep/linux/pci_ops_linux.c |    21 +
+ .../realtek/rtl8192cu/os_dep/linux/recv_linux.c    |   447 +
+ .../realtek/rtl8192cu/os_dep/linux/rtw_android.c   |   838 ++
+ .../realtek/rtl8192cu/os_dep/linux/usb_intf.c      |  1654 +++
+ .../realtek/rtl8192cu/os_dep/linux/usb_ops_linux.c |   648 +
+ .../realtek/rtl8192cu/os_dep/linux/xmit_linux.c    |   420 +
+ .../realtek/rtl8192cu/os_dep/osdep_service.c       |  2299 ++++
+ drivers/net/wireless/realtek/rtl8192cu/runwpa      |    18 +
+ drivers/net/wireless/realtek/rtl8192cu/wlan0dhcp   |    15 +
+ 174 files changed, 171243 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/Kconfig
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/Makefile
+ create mode 100755 drivers/net/wireless/realtek/rtl8192cu/clean
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/efuse/rtw_efuse.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_ap.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_br_ext.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_cmd.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_debug.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_eeprom.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_ieee80211.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_io.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_query.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_rtl.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_set.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_iol.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_mlme.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_mlme_ext.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_mp.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_mp_ioctl.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_p2p.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_pwrctrl.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_recv.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_rf.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_security.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_sreset.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_sta_mgt.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_tdls.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_wlan_util.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/core/rtw_xmit.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/HalPwrSeqCmd.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/dm.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/dm.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/hal_com.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/hal_intf.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_cmd.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_dm.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_hal_init.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_mp.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_phycfg.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_rf6052.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_rxdesc.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_sreset.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_xmit.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/Hal8192CUHWImg.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/Hal8192CUHWImg_wowlan.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/rtl8192cu_led.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/rtl8192cu_recv.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/rtl8192cu_xmit.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/usb_halinit.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/usb_ops_ce.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/usb_ops_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/usb/usb_ops_xp.c
+ create mode 100755 drivers/net/wireless/realtek/rtl8192cu/ifcfg-wlan0
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192CEHWImg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192CPhyCfg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192CPhyReg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192CUHWImg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192CUHWImg_wowlan.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192DEHWImg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192DPhyCfg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192DPhyReg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192DUHWImg.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/Hal8192DUHWImg_wowlan.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/HalPwrSeqCmd.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/autoconf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/basic_types.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/byteorder/big_endian.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/byteorder/generic.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/byteorder/little_endian.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/byteorder/swab.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/byteorder/swabb.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/circ_buf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/cmd_osdep.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/drv_conf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/drv_types.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/drv_types_ce.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/drv_types_linux.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/drv_types_sdio.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/drv_types_xp.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/ethernet.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/h2clbk.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/hal_com.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/hal_intf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/ieee80211.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/ieee80211_ext.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/if_ether.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/ioctl_cfg80211.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/ip.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/linux/wireless.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/mlme_osdep.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/mp_custom_oid.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/nic_spec.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/osdep_ce_service.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/osdep_intf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/osdep_service.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/pci_hal.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/pci_ops.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/pci_osintf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/recv_osdep.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_cmd.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_dm.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_event.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_hal.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_led.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_recv.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_rf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_spec.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_sreset.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192c_xmit.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_cmd.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_dm.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_hal.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_led.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_recv.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_rf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_spec.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtl8192d_xmit.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_android.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_ap.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_br_ext.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_byteorder.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_cmd.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_debug.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_eeprom.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_efuse.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_event.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_ht.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_io.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_ioctl.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_ioctl_query.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_ioctl_rtl.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_ioctl_set.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_iol.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_led.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_mlme.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_mlme_ext.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_mp.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_mp_ioctl.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_mp_phy_regdef.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_p2p.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_pwrctrl.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_qos.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_recv.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_rf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_security.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_sreset.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_tdls.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_version.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/rtw_xmit.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/sta_info.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/usb_hal.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/usb_ops.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/usb_ops_linux.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/usb_osintf.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/usb_vendor_req.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/wifi.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/wlan_bssdef.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/include/xmit_osdep.h
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/ioctl_cfg80211.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/ioctl_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/mlme_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/os_intfs.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/pci_intf.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/pci_ops_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/recv_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/rtw_android.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/usb_intf.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/usb_ops_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/linux/xmit_linux.c
+ create mode 100644 drivers/net/wireless/realtek/rtl8192cu/os_dep/osdep_service.c
+ create mode 100755 drivers/net/wireless/realtek/rtl8192cu/runwpa
+ create mode 100755 drivers/net/wireless/realtek/rtl8192cu/wlan0dhcp
+
+--- a/drivers/net/wireless/Kconfig
++++ b/drivers/net/wireless/Kconfig
+@@ -278,7 +278,8 @@ source "drivers/net/wireless/orinoco/Kco
+ source "drivers/net/wireless/p54/Kconfig"
+ source "drivers/net/wireless/rt2x00/Kconfig"
+ source "drivers/net/wireless/mediatek/Kconfig"
+-source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
++#source "drivers/net/wireless/realtek/rtlwifi/Kconfig"
++source "drivers/net/wireless/realtek/rtl8192cu/Kconfig"
+ source "drivers/net/wireless/realtek/rtl8xxxu/Kconfig"
+ source "drivers/net/wireless/ti/Kconfig"
+ source "drivers/net/wireless/zd1211rw/Kconfig"
+--- a/drivers/net/wireless/realtek/Makefile
++++ b/drivers/net/wireless/realtek/Makefile
+@@ -4,6 +4,7 @@
+ 
+ obj-$(CONFIG_RTL8180)		+= rtl818x/
+ obj-$(CONFIG_RTL8187)		+= rtl818x/
+-obj-$(CONFIG_RTLWIFI)		+= rtlwifi/
++#obj-$(CONFIG_RTLWIFI)		+= rtlwifi/
++obj-$(CONFIG_RTL8192CU)		+= rtl8192cu/
+ obj-$(CONFIG_RTL8XXXU)		+= rtl8xxxu/
+ 
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/Kconfig
+@@ -0,0 +1,9 @@
++config RTL8192CU
++	tristate "Realtek 8192C USB WiFi"
++	depends on MAC80211 && USB
++	select CFG80211_WEXT
++	select WIRELESS_EXT
++	select WEXT_PRIV
++	---help---
++	  This option adds the Realtek RTL8192CU USB device such as Edimax EW-7811Un.
++
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/Makefile
+@@ -0,0 +1,615 @@
++EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
++EXTRA_CFLAGS += -O1
++#EXTRA_CFLAGS += -O3
++#EXTRA_CFLAGS += -Wall
++#EXTRA_CFLAGS += -Wextra
++#EXTRA_CFLAGS += -Werror
++#EXTRA_CFLAGS += -pedantic
++#EXTRA_CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes
++
++EXTRA_CFLAGS += -Wno-unused-variable
++EXTRA_CFLAGS += -Wno-unused-value
++EXTRA_CFLAGS += -Wno-unused-label
++EXTRA_CFLAGS += -Wno-unused-parameter
++EXTRA_CFLAGS += -Wno-unused-function
++EXTRA_CFLAGS += -Wno-unused
++
++EXTRA_CFLAGS += -Wno-uninitialized
++
++EXTRA_CFLAGS += -I$(src)/include
++
++CONFIG_AUTOCFG_CP = n
++
++CONFIG_RTL8192C = y
++CONFIG_RTL8192D = n
++CONFIG_RTL8723A = n
++
++CONFIG_USB_HCI = y
++CONFIG_PCI_HCI = n
++CONFIG_SDIO_HCI = n
++
++CONFIG_MP_INCLUDED = n
++CONFIG_POWER_SAVING = y
++CONFIG_USB_AUTOSUSPEND = n
++CONFIG_HW_PWRP_DETECTION = n
++CONFIG_WIFI_TEST = n
++CONFIG_BT_COEXISTENCE = n
++CONFIG_RTL8192CU_REDEFINE_1X1 = n
++CONFIG_INTEL_WIDI = n
++CONFIG_WAKE_ON_WLAN = n
++
++CONFIG_PLATFORM_I386_PC = y
++CONFIG_PLATFORM_TI_AM3517 = n
++CONFIG_PLATFORM_ANDROID_X86 = n
++CONFIG_PLATFORM_JB_X86 = n
++CONFIG_PLATFORM_ARM_S3C2K4 = n
++CONFIG_PLATFORM_ARM_PXA2XX = n
++CONFIG_PLATFORM_ARM_S3C6K4 = n
++CONFIG_PLATFORM_MIPS_RMI = n
++CONFIG_PLATFORM_RTD2880B = n
++CONFIG_PLATFORM_MIPS_AR9132 = n
++CONFIG_PLATFORM_RTK_DMP = n
++CONFIG_PLATFORM_MIPS_PLM = n
++CONFIG_PLATFORM_MSTAR389 = n
++CONFIG_PLATFORM_MT53XX = n
++CONFIG_PLATFORM_ARM_MX51_241H = n
++CONFIG_PLATFORM_FS_MX61 = n
++CONFIG_PLATFORM_ACTIONS_ATJ227X = n
++CONFIG_PLATFORM_TEGRA3_CARDHU = n
++CONFIG_PLATFORM_TEGRA4_DALMORE = n
++CONFIG_PLATFORM_ARM_TCC8900 = n
++CONFIG_PLATFORM_ARM_TCC8920 = n
++CONFIG_PLATFORM_ARM_TCC8920_JB42 = n
++CONFIG_PLATFORM_ARM_RK2818 = n
++CONFIG_PLATFORM_ARM_TI_PANDA = n
++CONFIG_PLATFORM_MIPS_JZ4760 = n
++CONFIG_PLATFORM_DMP_PHILIPS = n
++CONFIG_PLATFORM_TI_DM365 = n
++CONFIG_PLATFORM_MN10300 = n
++CONFIG_PLATFORM_MSTAR_TITANIA12 = n
++CONFIG_PLATFORM_MSTAR_A3 = n
++CONFIG_PLATFORM_ARM_SUNxI = n
++CONFIG_PLATFORM_ARM_SUN6I = n
++
++CONFIG_DRVEXT_MODULE = n
++
++export TopDIR ?= $(shell pwd)
++
++
++ifeq ($(CONFIG_RTL8192C), y)
++
++RTL871X = rtl8192c
++
++ifeq ($(CONFIG_USB_HCI), y)
++MODULE_NAME = 8192cu
++FW_FILES := hal/$(RTL871X)/usb/Hal8192CUHWImg.o
++ifneq ($(CONFIG_WAKE_ON_WLAN), n)
++FW_FILES += hal/$(RTL871X)/usb/Hal8192CUHWImg_wowlan.o
++endif
++endif
++ifeq ($(CONFIG_PCI_HCI), y)
++MODULE_NAME = 8192ce
++FW_FILES := hal/$(RTL871X)/pci/Hal8192CEHWImg.o
++endif
++
++CHIP_FILES := \
++	hal/$(RTL871X)/$(RTL871X)_sreset.o \
++	hal/$(RTL871X)/$(RTL871X)_xmit.o
++CHIP_FILES += $(FW_FILES)
++endif
++
++ifeq ($(CONFIG_RTL8192D), y)
++
++RTL871X = rtl8192d
++
++ifeq ($(CONFIG_USB_HCI), y)
++MODULE_NAME = 8192du
++FW_FILES := hal/$(RTL871X)/usb/Hal8192DUHWImg.o
++ifneq ($(CONFIG_WAKE_ON_WLAN), n)
++FW_FILES += hal/$(RTL871X)/usb/Hal8192DUHWImg_wowlan.o
++endif
++endif
++ifeq ($(CONFIG_PCI_HCI), y)
++MODULE_NAME = 8192de
++FW_FILES := hal/$(RTL871X)/pci/Hal8192DEHWImg.o
++endif
++
++CHIP_FILES := \
++	hal/$(RTL871X)/$(RTL871X)_xmit.o
++CHIP_FILES += $(FW_FILES)
++endif
++
++ifeq ($(CONFIG_RTL8723A), y)
++
++RTL871X = rtl8723a
++
++ifeq ($(CONFIG_SDIO_HCI), y)
++MODULE_NAME = 8723as
++FW_FILES := hal/$(RTL871X)/sdio/Hal8723SHWImg.o
++endif
++
++ifeq ($(CONFIG_USB_HCI), y)
++MODULE_NAME = 8723au
++FW_FILES := hal/$(RTL871X)/usb/Hal8723UHWImg.o
++endif
++
++ifeq ($(CONFIG_PCI_HCI), y)
++MODULE_NAME = 8723ae
++FW_FILES := hal/$(RTL871X)/pci/Hal8723EHWImg.o
++endif
++
++PWRSEQ_FILES := hal/HalPwrSeqCmd.o \
++				hal/$(RTL871X)/Hal8723PwrSeq.o
++
++CHIP_FILES += $(FW_FILES) $(PWRSEQ_FILES)
++
++endif
++
++ifeq ($(CONFIG_SDIO_HCI), y)
++HCI_NAME = sdio
++endif
++
++ifeq ($(CONFIG_USB_HCI), y)
++HCI_NAME = usb
++endif
++
++ifeq ($(CONFIG_PCI_HCI), y)
++HCI_NAME = pci
++endif
++
++
++_OS_INTFS_FILES :=	os_dep/osdep_service.o \
++			os_dep/linux/os_intfs.o \
++			os_dep/linux/$(HCI_NAME)_intf.o \
++			os_dep/linux/$(HCI_NAME)_ops_linux.o \
++			os_dep/linux/ioctl_linux.o \
++			os_dep/linux/xmit_linux.o \
++			os_dep/linux/mlme_linux.o \
++			os_dep/linux/recv_linux.o \
++			os_dep/linux/ioctl_cfg80211.o \
++			os_dep/linux/rtw_android.o
++
++
++_HAL_INTFS_FILES :=	hal/hal_intf.o \
++			hal/hal_com.o \
++			hal/dm.o \
++			hal/$(RTL871X)/$(RTL871X)_hal_init.o \
++			hal/$(RTL871X)/$(RTL871X)_phycfg.o \
++			hal/$(RTL871X)/$(RTL871X)_rf6052.o \
++			hal/$(RTL871X)/$(RTL871X)_dm.o \
++			hal/$(RTL871X)/$(RTL871X)_rxdesc.o \
++			hal/$(RTL871X)/$(RTL871X)_cmd.o \
++			hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_halinit.o \
++			hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_led.o \
++			hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_xmit.o \
++			hal/$(RTL871X)/$(HCI_NAME)/rtl$(MODULE_NAME)_recv.o
++
++ifeq ($(CONFIG_SDIO_HCI), y)
++_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops.o
++else
++_HAL_INTFS_FILES += hal/$(RTL871X)/$(HCI_NAME)/$(HCI_NAME)_ops_linux.o
++endif
++
++ifeq ($(CONFIG_MP_INCLUDED), y)
++_HAL_INTFS_FILES += hal/$(RTL871X)/$(RTL871X)_mp.o
++endif
++
++_HAL_INTFS_FILES += $(CHIP_FILES)
++
++
++ifeq ($(CONFIG_AUTOCFG_CP), y)
++$(shell cp $(TopDIR)/autoconf_$(RTL871X)_$(HCI_NAME)_linux.h $(TopDIR)/include/autoconf.h)
++endif
++
++
++ifeq ($(CONFIG_USB_HCI), y)
++ifeq ($(CONFIG_USB_AUTOSUSPEND), y)
++EXTRA_CFLAGS += -DCONFIG_USB_AUTOSUSPEND
++endif
++endif
++
++ifeq ($(CONFIG_POWER_SAVING), y)
++EXTRA_CFLAGS += -DCONFIG_POWER_SAVING
++endif
++
++ifeq ($(CONFIG_HW_PWRP_DETECTION), y)
++EXTRA_CFLAGS += -DCONFIG_HW_PWRP_DETECTION
++endif
++
++ifeq ($(CONFIG_WIFI_TEST), y)
++EXTRA_CFLAGS += -DCONFIG_WIFI_TEST
++endif
++
++ifeq ($(CONFIG_BT_COEXISTENCE), y)
++EXTRA_CFLAGS += -DCONFIG_BT_COEXISTENCE
++endif
++
++ifeq ($(CONFIG_RTL8192CU_REDEFINE_1X1), y)
++EXTRA_CFLAGS += -DRTL8192C_RECONFIG_TO_1T1R
++endif
++
++ifeq ($(CONFIG_WAKE_ON_WLAN), y)
++EXTRA_CFLAGS += -DCONFIG_WAKE_ON_WLAN
++endif
++
++ifeq ($(CONFIG_INTEL_WIDI), y)
++EXTRA_CFLAGS += -DCONFIG_INTEL_WIDI
++endif
++
++ifeq ($(CONFIG_PLATFORM_I386_PC), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++SUBARCH := $(shell uname -m | sed -e s/i.86/i386/)
++ARCH ?= $(SUBARCH)
++CROSS_COMPILE ?=
++KVER  := $(shell uname -r)
++KSRC := /lib/modules/$(KVER)/build
++MODDESTDIR := /lib/modules/$(KVER)/kernel/drivers/net/wireless/
++INSTALL_PREFIX :=
++endif
++
++ifeq ($(CONFIG_PLATFORM_TI_AM3517), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_SHUTTLE
++CROSS_COMPILE := arm-eabi-
++KSRC := $(shell pwd)/../../../Android/kernel
++ARCH := arm
++endif
++
++ifeq ($(CONFIG_PLATFORM_MSTAR_TITANIA12), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR -DCONFIG_PLATFORM_MSTAR_TITANIA12
++ARCH:=mips
++CROSS_COMPILE:= /usr/src/Mstar_kernel/mips-4.3/bin/mips-linux-gnu-
++KVER:= 2.6.28.9
++KSRC:= /usr/src/Mstar_kernel/2.6.28.9/
++endif
++
++ifeq ($(CONFIG_PLATFORM_MSTAR_A3), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR -DCONFIG_PLATFORM_MSTAR_A3
++ARCH:=arm
++CROSS_COMPILE:= arm-none-linux-gnueabi-
++KVER:= 2.6.35.11
++KSRC:= /home/gary/PERFORCE/THEALE/RedLion/2.6.35.11/
++MODULE_NAME = wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ANDROID_X86), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++SUBARCH := $(shell uname -m | sed -e s/i.86/i386/)
++ARCH := $(SUBARCH)
++CROSS_COMPILE := /media/DATA-2/android-x86/ics-x86_20120130/prebuilt/linux-x86/toolchain/i686-unknown-linux-gnu-4.2.1/bin/i686-unknown-linux-gnu-
++KSRC := /media/DATA-2/android-x86/ics-x86_20120130/out/target/product/generic_x86/obj/kernel
++MODULE_NAME :=wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_JB_X86), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
++EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
++EXTRA_CFLAGS += -DCONFIG_P2P_IPS
++SUBARCH := $(shell uname -m | sed -e s/i.86/i386/)
++ARCH := $(SUBARCH)
++CROSS_COMPILE := /home/android_sdk/android-x86_JB/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7/bin/i686-linux-android-
++KSRC := /home/android_sdk/android-x86_JB/out/target/product/x86/obj/kernel/
++MODULE_NAME :=wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_PXA2XX), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH := arm
++CROSS_COMPILE := arm-none-linux-gnueabi-
++KVER  := 2.6.34.1
++KSRC ?= /usr/src/linux-2.6.34.1
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_S3C2K4), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH := arm
++CROSS_COMPILE := arm-linux-
++KVER  := 2.6.24.7_$(ARCH)
++KSRC := /usr/src/kernels/linux-$(KVER)
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_S3C6K4), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH := arm
++CROSS_COMPILE := arm-none-linux-gnueabi-
++KVER  := 2.6.34.1
++KSRC ?= /usr/src/linux-2.6.34.1
++endif
++
++ifeq ($(CONFIG_PLATFORM_RTD2880B), y)
++EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN -DCONFIG_PLATFORM_RTD2880B
++ARCH:=
++CROSS_COMPILE:=
++KVER:=
++KSRC:=
++endif
++
++ifeq ($(CONFIG_PLATFORM_MIPS_RMI), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH:=mips
++CROSS_COMPILE:=mipsisa32r2-uclibc-
++KVER:=
++KSRC:= /root/work/kernel_realtek
++endif
++
++ifeq ($(CONFIG_PLATFORM_MIPS_PLM), y)
++EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN
++ARCH:=mips
++CROSS_COMPILE:=mipsisa32r2-uclibc-
++KVER:=
++KSRC:= /root/work/kernel_realtek
++endif
++
++ifeq ($(CONFIG_PLATFORM_MSTAR389), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MSTAR389
++ARCH:=mips
++CROSS_COMPILE:= mips-linux-gnu-
++KVER:= 2.6.28.10
++KSRC:= /home/mstar/mstar_linux/2.6.28.9/
++endif
++
++ifeq ($(CONFIG_PLATFORM_MIPS_AR9132), y)
++EXTRA_CFLAGS += -DCONFIG_BIG_ENDIAN
++ARCH := mips
++CROSS_COMPILE := mips-openwrt-linux-
++KSRC := /home/alex/test_openwrt/tmp/linux-2.6.30.9
++endif
++
++ifeq ($(CONFIG_PLATFORM_DMP_PHILIPS), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DRTK_DMP_PLATFORM
++ARCH := mips
++#CROSS_COMPILE:=/usr/local/msdk-4.3.6-mips-EL-2.6.12.6-0.9.30.3/bin/mipsel-linux-
++CROSS_COMPILE:=/usr/local/toolchain_mipsel/bin/mipsel-linux-
++KSRC ?=/usr/local/Jupiter/linux-2.6.12
++endif
++
++ifeq ($(CONFIG_PLATFORM_RTK_DMP), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DRTK_DMP_PLATFORM
++ARCH:=mips
++CROSS_COMPILE:=mipsel-linux-
++KVER:=
++KSRC ?= /usr/src/DMP_Kernel/jupiter/linux-2.6.12
++endif
++
++ifeq ($(CONFIG_PLATFORM_MT53XX), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MT53XX
++ARCH:= arm
++CROSS_COMPILE:= arm11_mtk_le-
++KVER:= 2.6.27
++KSRC?= /proj/mtk00802/BD_Compare/BDP/Dev/BDP_V301/BDP_Linux/linux-2.6.27
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_MX51_241H), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_WISTRON_PLATFORM
++ARCH := arm
++CROSS_COMPILE := /opt/freescale/usr/local/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-
++KVER  := 2.6.31
++KSRC ?= /lib/modules/2.6.31-770-g0e46b52/source
++endif
++
++ifeq ($(CONFIG_PLATFORM_FS_MX61), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH := arm
++CROSS_COMPILE := /home/share/CusEnv/FreeScale/arm-eabi-4.4.3/bin/arm-eabi-
++KSRC ?= /home/share/CusEnv/FreeScale/FS_kernel_env
++endif
++
++
++
++ifeq ($(CONFIG_PLATFORM_ACTIONS_ATJ227X), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ACTIONS_ATJ227X
++ARCH := mips
++CROSS_COMPILE := /home/cnsd4/project/actions/tools-2.6.27/bin/mipsel-linux-gnu-
++KVER  := 2.6.27
++KSRC := /home/cnsd4/project/actions/linux-2.6.27.28
++endif
++
++ifeq ($(CONFIG_PLATFORM_TI_DM365), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_TI_DM365
++ARCH := arm
++CROSS_COMPILE := /home/cnsd4/Appro/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin/arm_v5t_le-
++KVER  := 2.6.18
++KSRC := /home/cnsd4/Appro/mv_pro_5.0/montavista/pro/devkit/lsp/ti-davinci/linux-dm365
++endif
++
++ifeq ($(CONFIG_PLATFORM_TEGRA3_CARDHU), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++# default setting for Android 4.1, 4.2
++EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC
++EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
++EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
++EXTRA_CFLAGS += -DCONFIG_P2P_IPS
++ARCH := arm
++CROSS_COMPILE := /home/android_sdk/nvidia/tegra-16r3-partner-android-4.1_20120723/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
++KSRC := /home/android_sdk/nvidia/tegra-16r3-partner-android-4.1_20120723/out/target/product/cardhu/obj/KERNEL
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_TEGRA4_DALMORE), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++# default setting for Android 4.1, 4.2
++EXTRA_CFLAGS += -DRTW_ENABLE_WIFI_CONTROL_FUNC
++EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
++EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
++EXTRA_CFLAGS += -DCONFIG_P2P_IPS
++ARCH := arm
++CROSS_COMPILE := /home/android_sdk/nvidia/tegra-17r9-partner-android-4.2-dalmore_20130131/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
++KSRC := /home/android_sdk/nvidia/tegra-17r9-partner-android-4.2-dalmore_20130131/out/target/product/dalmore/obj/KERNEL
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_TCC8900), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH := arm
++CROSS_COMPILE := /home/android_sdk/Telechips/SDK_2304_20110613/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
++KSRC := /home/android_sdk/Telechips/SDK_2304_20110613/kernel
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_TCC8920), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++ARCH := arm
++CROSS_COMPILE := /home/android_sdk/Telechips/v12.06_r1-tcc-android-4.0.4/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
++KSRC := /home/android_sdk/Telechips/v12.06_r1-tcc-android-4.0.4/kernel
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_TCC8920_JB42), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++# default setting for Android 4.1, 4.2
++EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
++EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
++EXTRA_CFLAGS += -DCONFIG_P2P_IPS
++ARCH := arm
++CROSS_COMPILE := /home/android_sdk/Telechips/v13.03_r1-tcc-android-4.2.2_ds_patched/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
++KSRC := /home/android_sdk/Telechips/v13.03_r1-tcc-android-4.2.2_ds_patched/kernel
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_RK2818), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ANDROID -DCONFIG_PLATFORM_ROCKCHIPS -DCONFIG_MINIMAL_MEMORY_USAGE
++ARCH := arm
++CROSS_COMPILE := /usr/src/release_fae_version/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
++KSRC := /usr/src/release_fae_version/kernel25_A7_281x
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_TI_PANDA), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN #-DCONFIG_MINIMAL_MEMORY_USAGE
++ARCH := arm
++#CROSS_COMPILE := /media/DATA-1/aosp/ics-aosp_20111227/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
++#KSRC := /media/DATA-1/aosp/android-omap-panda-3.0_20120104
++CROSS_COMPILE := /media/DATA-1/android-4.0/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
++KSRC := /media/DATA-1/android-4.0/panda_kernel/omap
++MODULE_NAME := wlan
++endif
++
++ifeq ($(CONFIG_PLATFORM_MIPS_JZ4760), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_MINIMAL_MEMORY_USAGE
++ARCH ?= mips
++CROSS_COMPILE ?= /mnt/sdb5/Ingenic/Umido/mips-4.3/bin/mips-linux-gnu-
++KSRC ?= /mnt/sdb5/Ingenic/Umido/kernel
++endif
++
++#Add setting for MN10300
++ifeq ($(CONFIG_PLATFORM_MN10300), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_MN10300
++ARCH := mn10300
++CROSS_COMPILE := mn10300-linux-
++KVER := 2.6.32.2
++KSRC := /home/winuser/work/Plat_sLD2T_V3010/usr/src/linux-2.6.32.2
++INSTALL_PREFIX :=
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_SUNxI), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN -DCONFIG_PLATFORM_ARM_SUNxI
++ARCH := arm
++CROSS_COMPILE := arm-none-linux-gnueabi-
++KVER  := 3.0.8
++#KSRC:= ../lichee/linux-3.0/
++endif
++
++ifeq ($(CONFIG_PLATFORM_ARM_SUN6I), y)
++EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
++EXTRA_CFLAGS += -DCONFIG_PLATFORM_ARM_SUN6I
++EXTRA_CFLAGS += -DCONFIG_USE_USB_BUFFER_ALLOC_TX
++EXTRA_CFLAGS += -DCONFIG_TRAFFIC_PROTECT
++# default setting for Android 4.1, 4.2
++EXTRA_CFLAGS += -DCONFIG_CONCURRENT_MODE
++EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
++EXTRA_CFLAGS += -DCONFIG_P2P_IPS
++ARCH := arm
++CROSS_COMPILE := arm-none-linux-gnueabi-
++KVER  := 3.3.0
++#KSRC:= ../lichee/linux-3.3/
++endif
++
++ifneq ($(USER_MODULE_NAME),)
++MODULE_NAME := $(USER_MODULE_NAME)
++endif
++
++ifeq ($(CONFIG_MP_INCLUDED), y)
++MODULE_NAME := $(MODULE_NAME)_mp
++EXTRA_CFLAGS += -DCONFIG_MP_INCLUDED
++endif
++
++
++ifneq ($(KERNELRELEASE),)
++
++
++rtk_core :=	core/rtw_cmd.o \
++		core/rtw_security.o \
++		core/rtw_debug.o \
++		core/rtw_io.o \
++		core/rtw_ioctl_query.o \
++		core/rtw_ioctl_set.o \
++		core/rtw_ieee80211.o \
++		core/rtw_mlme.o \
++		core/rtw_mlme_ext.o \
++		core/rtw_wlan_util.o \
++		core/rtw_pwrctrl.o \
++		core/rtw_rf.o \
++		core/rtw_recv.o \
++		core/rtw_sta_mgt.o \
++		core/rtw_ap.o \
++		core/rtw_xmit.o	\
++		core/rtw_p2p.o \
++		core/rtw_tdls.o \
++		core/rtw_br_ext.o \
++		core/rtw_iol.o \
++		core/rtw_sreset.o
++
++$(MODULE_NAME)-y += $(rtk_core)
++
++$(MODULE_NAME)-$(CONFIG_INTEL_WIDI) += core/rtw_intel_widi.o
++
++$(MODULE_NAME)-y += core/efuse/rtw_efuse.o
++
++$(MODULE_NAME)-y += $(_HAL_INTFS_FILES)
++
++$(MODULE_NAME)-y += $(_OS_INTFS_FILES)
++
++$(MODULE_NAME)-$(CONFIG_MP_INCLUDED) += core/rtw_mp.o \
++					core/rtw_mp_ioctl.o
++
++obj-$(CONFIG_RTL8192CU) := $(MODULE_NAME).o
++
++else
++
++export CONFIG_RTL8192CU = m
++
++all: modules
++
++modules:
++	$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KSRC) M=$(shell pwd)  modules
++
++strip:
++	$(CROSS_COMPILE)strip $(MODULE_NAME).ko --strip-unneeded
++
++install:
++	install -p -m 644 $(MODULE_NAME).ko  $(MODDESTDIR)
++	/sbin/depmod -a ${KVER}
++
++uninstall:
++	rm -f $(MODDESTDIR)/$(MODULE_NAME).ko
++	/sbin/depmod -a ${KVER}
++
++
++config_r:
++	@echo "make config"
++	/bin/bash script/Configure script/config.in
++
++.PHONY: modules clean
++
++clean:
++	rm -fr *.mod.c *.mod *.o .*.cmd *.ko *~
++	rm .tmp_versions -fr ; rm Module.symvers -fr
++	rm -fr Module.markers ; rm -fr modules.order
++	cd core/efuse ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++	cd core ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++	cd hal/$(RTL871X)/$(HCI_NAME) ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++	cd hal/$(RTL871X) ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++	cd hal ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++	cd os_dep/linux ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++	cd os_dep ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko
++endif
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/clean
+@@ -0,0 +1,5 @@
++#!/bin/bash
++rmmod 8192cu
++rmmod 8192ce
++rmmod 8192du
++rmmod 8192de
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/efuse/rtw_efuse.c
+@@ -0,0 +1,1145 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_EFUSE_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++
++#include <rtw_efuse.h>
++
++
++
++/*------------------------Define local variable------------------------------*/
++u8	fakeEfuseBank=0;
++u32	fakeEfuseUsedBytes=0;
++u8	fakeEfuseContent[EFUSE_MAX_HW_SIZE]={0};
++u8	fakeEfuseInitMap[EFUSE_MAX_MAP_LEN]={0};
++u8	fakeEfuseModifiedMap[EFUSE_MAX_MAP_LEN]={0};
++
++u32	BTEfuseUsedBytes=0;
++u8	BTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
++u8	BTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0};
++u8	BTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0};
++
++u32	fakeBTEfuseUsedBytes=0;
++u8	fakeBTEfuseContent[EFUSE_MAX_BT_BANK][EFUSE_MAX_HW_SIZE];
++u8	fakeBTEfuseInitMap[EFUSE_BT_MAX_MAP_LEN]={0};
++u8	fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]={0};
++/*------------------------Define local variable------------------------------*/
++
++//------------------------------------------------------------------------------
++#define REG_EFUSE_CTRL		0x0030
++#define EFUSE_CTRL			REG_EFUSE_CTRL		// E-Fuse Control.
++//------------------------------------------------------------------------------
++
++BOOLEAN
++Efuse_Read1ByteFromFakeContent(
++	IN		PADAPTER	pAdapter,
++	IN		u16		Offset,
++	IN OUT	u8		*Value	);
++BOOLEAN
++Efuse_Read1ByteFromFakeContent(
++	IN		PADAPTER	pAdapter,
++	IN		u16		Offset,
++	IN OUT	u8		*Value	)
++{
++	if(Offset >= EFUSE_MAX_HW_SIZE)
++	{
++		return _FALSE;
++	}
++	//DbgPrint("Read fake content, offset = %d\n", Offset);
++	if(fakeEfuseBank == 0)
++		*Value = fakeEfuseContent[Offset];
++	else
++		*Value = fakeBTEfuseContent[fakeEfuseBank-1][Offset];
++	return _TRUE;
++}
++
++BOOLEAN
++Efuse_Write1ByteToFakeContent(
++	IN		PADAPTER	pAdapter,
++	IN		u16		Offset,
++	IN 		u8		Value	);
++BOOLEAN
++Efuse_Write1ByteToFakeContent(
++	IN		PADAPTER	pAdapter,
++	IN		u16		Offset,
++	IN 		u8		Value	)
++{
++	if(Offset >= EFUSE_MAX_HW_SIZE)
++	{
++		return _FALSE;
++	}
++	if(fakeEfuseBank == 0)
++		fakeEfuseContent[Offset] = Value;
++	else
++	{
++		fakeBTEfuseContent[fakeEfuseBank-1][Offset] = Value;
++	}
++	return _TRUE;
++}
++
++/*-----------------------------------------------------------------------------
++ * Function:	Efuse_PowerSwitch
++ *
++ * Overview:	When we want to enable write operation, we should change to
++ *				pwr on state. When we stop write, we should switch to 500k mode
++ *				and disable LDO 2.5V.
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/17/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++VOID
++Efuse_PowerSwitch(
++	IN	PADAPTER	pAdapter,
++	IN	u8		bWrite,
++	IN	u8		PwrState)
++{
++	pAdapter->HalFunc.EfusePowerSwitch(pAdapter, bWrite, PwrState);
++}
++
++/*-----------------------------------------------------------------------------
++ * Function:	efuse_GetCurrentSize
++ *
++ * Overview:	Get current efuse size!!!
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/16/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++u16
++Efuse_GetCurrentSize(
++	IN PADAPTER		pAdapter,
++	IN u8			efuseType,
++	IN BOOLEAN		bPseudoTest)
++{
++	u16 ret=0;
++
++	ret = pAdapter->HalFunc.EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);
++
++	return ret;
++}
++
++/*  11/16/2008 MH Add description. Get current efuse area enabled word!!. */
++u8
++Efuse_CalculateWordCnts(IN u8	word_en)
++{
++	u8 word_cnts = 0;
++	if(!(word_en & BIT(0)))	word_cnts++; // 0 : write enable
++	if(!(word_en & BIT(1)))	word_cnts++;
++	if(!(word_en & BIT(2)))	word_cnts++;
++	if(!(word_en & BIT(3)))	word_cnts++;
++	return word_cnts;
++}
++
++//
++//	Description:
++//		Execute E-Fuse read byte operation.
++//		Refered from SD1 Richard.
++//
++//	Assumption:
++//		1. Boot from E-Fuse and successfully auto-load.
++//		2. PASSIVE_LEVEL (USB interface)
++//
++//	Created by Roger, 2008.10.21.
++//
++VOID
++ReadEFuseByte(
++		PADAPTER	Adapter,
++		u16 			_offset,
++		u8 			*pbuf,
++		IN BOOLEAN	bPseudoTest)
++{
++	u32	value32;
++	u8	readbyte;
++	u16	retry;
++	//u32 start=rtw_get_current_time();
++
++	if(bPseudoTest)
++	{
++		Efuse_Read1ByteFromFakeContent(Adapter, _offset, pbuf);
++		return;
++	}
++
++	//Write Address
++	rtw_write8(Adapter, EFUSE_CTRL+1, (_offset & 0xff));
++	readbyte = rtw_read8(Adapter, EFUSE_CTRL+2);
++	rtw_write8(Adapter, EFUSE_CTRL+2, ((_offset >> 8) & 0x03) | (readbyte & 0xfc));
++
++	//Write bit 32 0
++	readbyte = rtw_read8(Adapter, EFUSE_CTRL+3);
++	rtw_write8(Adapter, EFUSE_CTRL+3, (readbyte & 0x7f));
++
++	//Check bit 32 read-ready
++	retry = 0;
++	value32 = rtw_read32(Adapter, EFUSE_CTRL);
++	//while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10))
++	while(!(((value32 >> 24) & 0xff) & 0x80)  && (retry<10000))
++	{
++		value32 = rtw_read32(Adapter, EFUSE_CTRL);
++		retry++;
++	}
++
++	// 20100205 Joseph: Add delay suggested by SD1 Victor.
++	// This fix the problem that Efuse read error in high temperature condition.
++	// Designer says that there shall be some delay after ready bit is set, or the
++	// result will always stay on last data we read.
++	rtw_udelay_os(50);
++	value32 = rtw_read32(Adapter, EFUSE_CTRL);
++
++	*pbuf = (u8)(value32 & 0xff);
++	//DBG_871X("ReadEFuseByte _offset:%08u, in %d ms\n",_offset ,rtw_get_passing_time_ms(start));
++
++}
++
++
++//
++//	Description:
++//		1. Execute E-Fuse read byte operation according as map offset and
++//		    save to E-Fuse table.
++//		2. Refered from SD1 Richard.
++//
++//	Assumption:
++//		1. Boot from E-Fuse and successfully auto-load.
++//		2. PASSIVE_LEVEL (USB interface)
++//
++//	Created by Roger, 2008.10.21.
++//
++//	2008/12/12 MH 	1. Reorganize code flow and reserve bytes. and add description.
++//					2. Add efuse utilization collect.
++//	2008/12/22 MH	Read Efuse must check if we write section 1 data again!!! Sec1
++//					write addr must be after sec5.
++//
++
++VOID
++efuse_ReadEFuse(
++	PADAPTER	Adapter,
++	u8		efuseType,
++	u16		_offset,
++	u16 		_size_byte,
++	u8      	*pbuf,
++	IN	BOOLEAN	bPseudoTest
++	);
++VOID
++efuse_ReadEFuse(
++	PADAPTER	Adapter,
++	u8		efuseType,
++	u16		_offset,
++	u16 		_size_byte,
++	u8      	*pbuf,
++	IN	BOOLEAN	bPseudoTest
++	)
++{
++	Adapter->HalFunc.ReadEFuse(Adapter, efuseType, _offset, _size_byte, pbuf, bPseudoTest);
++}
++
++VOID
++EFUSE_GetEfuseDefinition(
++	IN		PADAPTER	pAdapter,
++	IN		u8		efuseType,
++	IN		u8		type,
++	OUT		void		*pOut,
++	IN		BOOLEAN		bPseudoTest
++	)
++{
++	pAdapter->HalFunc.EFUSEGetEfuseDefinition(pAdapter, efuseType, type, pOut, bPseudoTest);
++}
++
++/*-----------------------------------------------------------------------------
++ * Function:	EFUSE_Read1Byte
++ *
++ * Overview:	Copy from WMAC fot EFUSE read 1 byte.
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 09/23/2008 	MHC		Copy from WMAC.
++ *
++ *---------------------------------------------------------------------------*/
++u8
++EFUSE_Read1Byte(
++	IN	PADAPTER	Adapter,
++	IN	u16		Address)
++{
++	u8	data;
++	u8	Bytetemp = {0x00};
++	u8	temp = {0x00};
++	u32	k=0;
++	u16	contentLen=0;
++
++	EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE);
++
++	if (Address < contentLen)	//E-fuse 512Byte
++	{
++		//Write E-fuse Register address bit0~7
++		temp = Address & 0xFF;
++		rtw_write8(Adapter, EFUSE_CTRL+1, temp);
++		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
++		//Write E-fuse Register address bit8~9
++		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
++		rtw_write8(Adapter, EFUSE_CTRL+2, temp);
++
++		//Write 0x30[31]=0
++		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
++		temp = Bytetemp & 0x7F;
++		rtw_write8(Adapter, EFUSE_CTRL+3, temp);
++
++		//Wait Write-ready (0x30[31]=1)
++		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
++		while(!(Bytetemp & 0x80))
++		{
++			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
++			k++;
++			if(k==1000)
++			{
++				k=0;
++				break;
++			}
++		}
++		data=rtw_read8(Adapter, EFUSE_CTRL);
++		return data;
++	}
++	else
++		return 0xFF;
++
++}/* EFUSE_Read1Byte */
++
++/*-----------------------------------------------------------------------------
++ * Function:	EFUSE_Write1Byte
++ *
++ * Overview:	Copy from WMAC fot EFUSE write 1 byte.
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 09/23/2008 	MHC		Copy from WMAC.
++ *
++ *---------------------------------------------------------------------------*/
++
++void
++EFUSE_Write1Byte(
++	IN	PADAPTER	Adapter,
++	IN	u16		Address,
++	IN	u8		Value);
++void
++EFUSE_Write1Byte(
++	IN	PADAPTER	Adapter,
++	IN	u16		Address,
++	IN	u8		Value)
++{
++	u8	Bytetemp = {0x00};
++	u8	temp = {0x00};
++	u32	k=0;
++	u16	contentLen=0;
++
++	//RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr=%x Data =%x\n", Address, Value));
++	EFUSE_GetEfuseDefinition(Adapter, EFUSE_WIFI , TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&contentLen, _FALSE);
++
++	if( Address < contentLen)	//E-fuse 512Byte
++	{
++		rtw_write8(Adapter, EFUSE_CTRL, Value);
++
++		//Write E-fuse Register address bit0~7
++		temp = Address & 0xFF;
++		rtw_write8(Adapter, EFUSE_CTRL+1, temp);
++		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+2);
++
++		//Write E-fuse Register address bit8~9
++		temp = ((Address >> 8) & 0x03) | (Bytetemp & 0xFC);
++		rtw_write8(Adapter, EFUSE_CTRL+2, temp);
++
++		//Write 0x30[31]=1
++		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
++		temp = Bytetemp | 0x80;
++		rtw_write8(Adapter, EFUSE_CTRL+3, temp);
++
++		//Wait Write-ready (0x30[31]=0)
++		Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
++		while(Bytetemp & 0x80)
++		{
++			Bytetemp = rtw_read8(Adapter, EFUSE_CTRL+3);
++			k++;
++			if(k==100)
++			{
++				k=0;
++				break;
++			}
++		}
++	}
++}/* EFUSE_Write1Byte */
++
++/*  11/16/2008 MH Read one byte from real Efuse. */
++u8
++efuse_OneByteRead(
++	IN	PADAPTER	pAdapter,
++	IN	u16			addr,
++	IN	u8			*data,
++	IN	BOOLEAN		bPseudoTest)
++{
++	u8	tmpidx = 0;
++	u8	bResult;
++
++	if(bPseudoTest)
++	{
++		bResult = Efuse_Read1ByteFromFakeContent(pAdapter, addr, data);
++		return bResult;
++	}
++	// -----------------e-fuse reg ctrl ---------------------------------
++	//address
++	rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
++	rtw_write8(pAdapter, EFUSE_CTRL+2, ((u8)((addr>>8) &0x03) ) |
++	(rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC ));
++
++	rtw_write8(pAdapter, EFUSE_CTRL+3,  0x72);//read cmd
++
++	while(!(0x80 &rtw_read8(pAdapter, EFUSE_CTRL+3))&&(tmpidx<100))
++	{
++		tmpidx++;
++	}
++	if(tmpidx<100)
++	{
++		*data=rtw_read8(pAdapter, EFUSE_CTRL);
++		bResult = _TRUE;
++	}
++	else
++	{
++		*data = 0xff;
++		bResult = _FALSE;
++	}
++	return bResult;
++}
++
++/*  11/16/2008 MH Write one byte to reald Efuse. */
++u8
++efuse_OneByteWrite(
++	IN	PADAPTER	pAdapter,
++	IN	u16			addr,
++	IN	u8			data,
++	IN	BOOLEAN		bPseudoTest)
++{
++	u8	tmpidx = 0;
++	u8	bResult;
++
++	if(bPseudoTest)
++	{
++		bResult = Efuse_Write1ByteToFakeContent(pAdapter, addr, data);
++		return bResult;
++	}
++	//RT_TRACE(COMP_EFUSE, DBG_LOUD, ("Addr = %x Data=%x\n", addr, data));
++
++	//return	0;
++
++	// -----------------e-fuse reg ctrl ---------------------------------
++	//address
++	rtw_write8(pAdapter, EFUSE_CTRL+1, (u8)(addr&0xff));
++	rtw_write8(pAdapter, EFUSE_CTRL+2,
++	(rtw_read8(pAdapter, EFUSE_CTRL+2)&0xFC )|(u8)((addr>>8)&0x03) );
++	rtw_write8(pAdapter, EFUSE_CTRL, data);//data
++
++	rtw_write8(pAdapter, EFUSE_CTRL+3, 0xF2);//write cmd
++
++	while((0x80 &  rtw_read8(pAdapter, EFUSE_CTRL+3)) && (tmpidx<100) ){
++		tmpidx++;
++	}
++
++	if(tmpidx<100)
++	{
++		bResult = _TRUE;
++	}
++	else
++	{
++		bResult = _FALSE;
++	}
++
++	return bResult;
++}
++
++int
++Efuse_PgPacketRead(	IN	PADAPTER	pAdapter,
++					IN	u8			offset,
++					IN	u8			*data,
++					IN	BOOLEAN		bPseudoTest)
++{
++	int	ret=0;
++
++	ret =  pAdapter->HalFunc.Efuse_PgPacketRead(pAdapter, offset, data, bPseudoTest);
++
++	return ret;
++}
++
++int
++Efuse_PgPacketWrite(IN	PADAPTER	pAdapter,
++					IN	u8 			offset,
++					IN	u8			word_en,
++					IN	u8			*data,
++					IN	BOOLEAN		bPseudoTest)
++{
++	int ret;
++
++	ret =  pAdapter->HalFunc.Efuse_PgPacketWrite(pAdapter, offset, word_en, data, bPseudoTest);
++
++	return ret;
++}
++
++/*-----------------------------------------------------------------------------
++ * Function:	efuse_WordEnableDataRead
++ *
++ * Overview:	Read allowed word in current efuse section data.
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/16/2008 	MHC		Create Version 0.
++ * 11/21/2008 	MHC		Fix Write bug when we only enable late word.
++ *
++ *---------------------------------------------------------------------------*/
++void
++efuse_WordEnableDataRead(IN	u8	word_en,
++							IN	u8	*sourdata,
++							IN	u8	*targetdata)
++{
++	if (!(word_en&BIT(0)))
++	{
++		targetdata[0] = sourdata[0];
++		targetdata[1] = sourdata[1];
++	}
++	if (!(word_en&BIT(1)))
++	{
++		targetdata[2] = sourdata[2];
++		targetdata[3] = sourdata[3];
++	}
++	if (!(word_en&BIT(2)))
++	{
++		targetdata[4] = sourdata[4];
++		targetdata[5] = sourdata[5];
++	}
++	if (!(word_en&BIT(3)))
++	{
++		targetdata[6] = sourdata[6];
++		targetdata[7] = sourdata[7];
++	}
++}
++
++
++u8
++Efuse_WordEnableDataWrite(	IN	PADAPTER	pAdapter,
++							IN	u16		efuse_addr,
++							IN	u8		word_en,
++							IN	u8		*data,
++							IN	BOOLEAN		bPseudoTest)
++{
++	u8	ret=0;
++
++	ret =  pAdapter->HalFunc.Efuse_WordEnableDataWrite(pAdapter, efuse_addr, word_en, data, bPseudoTest);
++
++	return ret;
++}
++
++static u8 efuse_read8(PADAPTER padapter, u16 address, u8 *value)
++{
++	return efuse_OneByteRead(padapter,address, value, _FALSE);
++}
++
++static u8 efuse_write8(PADAPTER padapter, u16 address, u8 *value)
++{
++	return efuse_OneByteWrite(padapter,address, *value, _FALSE);
++}
++
++/*
++ * read/wirte raw efuse data
++ */
++u8 rtw_efuse_access(PADAPTER padapter, u8 bWrite, u16 start_addr, u16 cnts, u8 *data)
++{
++	int i = 0;
++	u16	real_content_len = 0, max_available_size = 0;
++	u8 res = _FAIL ;
++	u8 (*rw8)(PADAPTER, u16, u8*);
++
++	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN, (PVOID)&real_content_len, _FALSE);
++	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_available_size, _FALSE);
++
++	if (start_addr > real_content_len)
++		return _FAIL;
++
++	if (_TRUE == bWrite) {
++		if ((start_addr + cnts) > max_available_size)
++			return _FAIL;
++		rw8 = &efuse_write8;
++	} else
++		rw8 = &efuse_read8;
++
++	Efuse_PowerSwitch(padapter, bWrite, _TRUE);
++
++	// e-fuse one byte read / write
++	for (i = 0; i < cnts; i++) {
++		if (start_addr >= real_content_len) {
++			res = _FAIL;
++			break;
++		}
++
++		res = rw8(padapter, start_addr++, data++);
++		if (_FAIL == res) break;
++	}
++
++	Efuse_PowerSwitch(padapter, bWrite, _FALSE);
++
++	return res;
++}
++//------------------------------------------------------------------------------
++u16 efuse_GetMaxSize(PADAPTER padapter)
++{
++	u16	max_size;
++	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI , TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, (PVOID)&max_size, _FALSE);
++	return max_size;
++}
++//------------------------------------------------------------------------------
++u8 efuse_GetCurrentSize(PADAPTER padapter, u16 *size)
++{
++	Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
++	*size = Efuse_GetCurrentSize(padapter, EFUSE_WIFI, _FALSE);
++	Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
++
++	return _SUCCESS;
++}
++//------------------------------------------------------------------------------
++u8 rtw_efuse_map_read(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
++{
++	u16	mapLen=0;
++
++	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
++
++	if ((addr + cnts) > mapLen)
++		return _FAIL;
++
++	Efuse_PowerSwitch(padapter, _FALSE, _TRUE);
++
++	efuse_ReadEFuse(padapter, EFUSE_WIFI, addr, cnts, data, _FALSE);
++
++	Efuse_PowerSwitch(padapter, _FALSE, _FALSE);
++
++	return _SUCCESS;
++}
++//------------------------------------------------------------------------------
++u8 rtw_efuse_map_write(PADAPTER padapter, u16 addr, u16 cnts, u8 *data)
++{
++	u8	offset, word_en;
++	u8	*map;
++	u8	newdata[PGPKT_DATA_SIZE];
++	s32	i, j, idx;
++	u8	ret = _SUCCESS;
++	u16	mapLen=0;
++
++	EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, _FALSE);
++
++	if ((addr + cnts) > mapLen)
++		return _FAIL;
++
++	map = rtw_zmalloc(mapLen);
++	if(map == NULL){
++		return _FAIL;
++	}
++
++	ret = rtw_efuse_map_read(padapter, 0, mapLen, map);
++	if (ret == _FAIL) goto exit;
++
++	Efuse_PowerSwitch(padapter, _TRUE, _TRUE);
++
++	offset = (addr >> 3);
++	word_en = 0xF;
++	_rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
++	i = addr & 0x7;	// index of one package
++	j = 0;		// index of new package
++	idx = 0;	// data index
++
++	if (i & 0x1) {
++		// odd start
++		if (data[idx] != map[addr+idx]) {
++			word_en &= ~BIT(i >> 1);
++			newdata[i-1] = map[addr+idx-1];
++			newdata[i] = data[idx];
++		}
++		i++;
++		idx++;
++	}
++	do {
++		for (; i < PGPKT_DATA_SIZE; i += 2)
++		{
++			if (cnts == idx) break;
++			if ((cnts - idx) == 1) {
++				if (data[idx] != map[addr+idx]) {
++					word_en &= ~BIT(i >> 1);
++					newdata[i] = data[idx];
++					newdata[i+1] = map[addr+idx+1];
++				}
++				idx++;
++				break;
++			} else {
++				if ((data[idx] != map[addr+idx]) ||
++				    (data[idx+1] != map[addr+idx+1]))
++				{
++					word_en &= ~BIT(i >> 1);
++					newdata[i] = data[idx];
++					newdata[i+1] = data[idx + 1];
++				}
++				idx += 2;
++			}
++			if (idx == cnts) break;
++		}
++
++		if (word_en != 0xF) {
++			ret = Efuse_PgPacketWrite(padapter, offset, word_en, newdata, _FALSE);
++			DBG_871X("offset=%x \n",offset);
++			DBG_871X("word_en=%x \n",word_en);
++
++			for(i=0;i<PGPKT_DATA_SIZE;i++)
++			{
++				DBG_871X("data=%x \t",newdata[i]);
++			}
++			if (ret == _FAIL) break;
++		}
++
++		if (idx == cnts) break;
++
++		offset++;
++		i = 0;
++		j = 0;
++		word_en = 0xF;
++		_rtw_memset(newdata, 0xFF, PGPKT_DATA_SIZE);
++	} while (1);
++
++	Efuse_PowerSwitch(padapter, _TRUE, _FALSE);
++
++exit:
++
++	rtw_mfree(map, mapLen);
++
++	return ret;
++}
++
++
++/*-----------------------------------------------------------------------------
++ * Function:	Efuse_ReadAllMap
++ *
++ * Overview:	Read All Efuse content
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/11/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++VOID
++Efuse_ReadAllMap(
++	IN		PADAPTER	pAdapter,
++	IN		u8		efuseType,
++	IN OUT	u8		*Efuse,
++	IN		BOOLEAN		bPseudoTest);
++VOID
++Efuse_ReadAllMap(
++	IN		PADAPTER	pAdapter,
++	IN		u8		efuseType,
++	IN OUT	u8		*Efuse,
++	IN		BOOLEAN		bPseudoTest)
++{
++	u16	mapLen=0;
++
++	Efuse_PowerSwitch(pAdapter,_FALSE, _TRUE);
++
++	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
++
++	efuse_ReadEFuse(pAdapter, efuseType, 0, mapLen, Efuse, bPseudoTest);
++
++	Efuse_PowerSwitch(pAdapter,_FALSE, _FALSE);
++}
++
++/*-----------------------------------------------------------------------------
++ * Function:	efuse_ShadowRead1Byte
++ *			efuse_ShadowRead2Byte
++ *			efuse_ShadowRead4Byte
++ *
++ * Overview:	Read from efuse init map by one/two/four bytes !!!!!
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/12/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++static VOID
++efuse_ShadowRead1Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN OUT	u8		*Value)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++
++	*Value = pEEPROM->efuse_eeprom_data[Offset];
++
++}	// EFUSE_ShadowRead1Byte
++
++//---------------Read Two Bytes
++static VOID
++efuse_ShadowRead2Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN OUT	u16		*Value)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++
++	*Value = pEEPROM->efuse_eeprom_data[Offset];
++	*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
++
++}	// EFUSE_ShadowRead2Byte
++
++//---------------Read Four Bytes
++static VOID
++efuse_ShadowRead4Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN OUT	u32		*Value)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++
++	*Value = pEEPROM->efuse_eeprom_data[Offset];
++	*Value |= pEEPROM->efuse_eeprom_data[Offset+1]<<8;
++	*Value |= pEEPROM->efuse_eeprom_data[Offset+2]<<16;
++	*Value |= pEEPROM->efuse_eeprom_data[Offset+3]<<24;
++
++}	// efuse_ShadowRead4Byte
++
++
++/*-----------------------------------------------------------------------------
++ * Function:	efuse_ShadowWrite1Byte
++ *			efuse_ShadowWrite2Byte
++ *			efuse_ShadowWrite4Byte
++ *
++ * Overview:	Write efuse modify map by one/two/four byte.
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/12/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++#ifdef PLATFORM
++static VOID
++efuse_ShadowWrite1Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN 	u8		Value);
++#endif //PLATFORM
++static VOID
++efuse_ShadowWrite1Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN 	u8		Value)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++
++	pEEPROM->efuse_eeprom_data[Offset] = Value;
++
++}	// efuse_ShadowWrite1Byte
++
++//---------------Write Two Bytes
++static VOID
++efuse_ShadowWrite2Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN 	u16		Value)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++
++	pEEPROM->efuse_eeprom_data[Offset] = Value&0x00FF;
++	pEEPROM->efuse_eeprom_data[Offset+1] = Value>>8;
++
++}	// efuse_ShadowWrite1Byte
++
++//---------------Write Four Bytes
++static VOID
++efuse_ShadowWrite4Byte(
++	IN	PADAPTER	pAdapter,
++	IN	u16		Offset,
++	IN	u32		Value)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++
++	pEEPROM->efuse_eeprom_data[Offset] = (u8)(Value&0x000000FF);
++	pEEPROM->efuse_eeprom_data[Offset+1] = (u8)((Value>>8)&0x0000FF);
++	pEEPROM->efuse_eeprom_data[Offset+2] = (u8)((Value>>16)&0x00FF);
++	pEEPROM->efuse_eeprom_data[Offset+3] = (u8)((Value>>24)&0xFF);
++
++}	// efuse_ShadowWrite1Byte
++
++/*-----------------------------------------------------------------------------
++ * Function:	EFUSE_ShadowMapUpdate
++ *
++ * Overview:	Transfer current EFUSE content to shadow init and modify map.
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/13/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++void EFUSE_ShadowMapUpdate(
++	IN PADAPTER	pAdapter,
++	IN u8		efuseType,
++	IN BOOLEAN	bPseudoTest)
++{
++	EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
++	u16	mapLen=0;
++
++	EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_MAP_LEN, (PVOID)&mapLen, bPseudoTest);
++
++	if (pEEPROM->bautoload_fail_flag == _TRUE)
++	{
++		_rtw_memset(pEEPROM->efuse_eeprom_data, 0xFF, mapLen);
++	}
++	else
++	{
++		#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
++		if(_SUCCESS != retriveAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pEEPROM)) {
++		#endif
++
++		Efuse_ReadAllMap(pAdapter, efuseType, pEEPROM->efuse_eeprom_data, bPseudoTest);
++
++		#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
++			storeAdaptorInfoFile(pAdapter->registrypriv.adaptor_info_caching_file_path, pEEPROM);
++		}
++		#endif
++	}
++
++	//PlatformMoveMemory((PVOID)&pHalData->EfuseMap[EFUSE_MODIFY_MAP][0],
++	//(PVOID)&pHalData->EfuseMap[EFUSE_INIT_MAP][0], mapLen);
++}// EFUSE_ShadowMapUpdate
++
++
++/*-----------------------------------------------------------------------------
++ * Function:	EFUSE_ShadowRead
++ *
++ * Overview:	Read from efuse init map !!!!!
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/12/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++void
++EFUSE_ShadowRead(
++	IN		PADAPTER	pAdapter,
++	IN		u8		Type,
++	IN		u16		Offset,
++	IN OUT	u32		*Value	)
++{
++	if (Type == 1)
++		efuse_ShadowRead1Byte(pAdapter, Offset, (u8 *)Value);
++	else if (Type == 2)
++		efuse_ShadowRead2Byte(pAdapter, Offset, (u16 *)Value);
++	else if (Type == 4)
++		efuse_ShadowRead4Byte(pAdapter, Offset, (u32 *)Value);
++
++}	// EFUSE_ShadowRead
++
++/*-----------------------------------------------------------------------------
++ * Function:	EFUSE_ShadowWrite
++ *
++ * Overview:	Write efuse modify map for later update operation to use!!!!!
++ *
++ * Input:       NONE
++ *
++ * Output:      NONE
++ *
++ * Return:      NONE
++ *
++ * Revised History:
++ * When			Who		Remark
++ * 11/12/2008 	MHC		Create Version 0.
++ *
++ *---------------------------------------------------------------------------*/
++VOID
++EFUSE_ShadowWrite(
++	IN	PADAPTER	pAdapter,
++	IN	u8		Type,
++	IN	u16		Offset,
++	IN OUT	u32		Value);
++VOID
++EFUSE_ShadowWrite(
++	IN	PADAPTER	pAdapter,
++	IN	u8		Type,
++	IN	u16		Offset,
++	IN OUT	u32		Value)
++{
++#if (MP_DRIVER == 0)
++	return;
++#endif
++
++	if (Type == 1)
++		efuse_ShadowWrite1Byte(pAdapter, Offset, (u8)Value);
++	else if (Type == 2)
++		efuse_ShadowWrite2Byte(pAdapter, Offset, (u16)Value);
++	else if (Type == 4)
++		efuse_ShadowWrite4Byte(pAdapter, Offset, (u32)Value);
++
++}	// EFUSE_ShadowWrite
++
++VOID
++Efuse_InitSomeVar(
++	IN		PADAPTER	pAdapter
++	);
++VOID
++Efuse_InitSomeVar(
++	IN		PADAPTER	pAdapter
++	)
++{
++	u8 i;
++
++	_rtw_memset((PVOID)&fakeEfuseContent[0], 0xff, EFUSE_MAX_HW_SIZE);
++	_rtw_memset((PVOID)&fakeEfuseInitMap[0], 0xff, EFUSE_MAX_MAP_LEN);
++	_rtw_memset((PVOID)&fakeEfuseModifiedMap[0], 0xff, EFUSE_MAX_MAP_LEN);
++
++	for(i=0; i<EFUSE_MAX_BT_BANK; i++)
++	{
++		_rtw_memset((PVOID)&BTEfuseContent[i][0], EFUSE_MAX_HW_SIZE, 0xff);
++	}
++	_rtw_memset((PVOID)&BTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
++	_rtw_memset((PVOID)&BTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
++
++	for(i=0; i<EFUSE_MAX_BT_BANK; i++)
++	{
++		_rtw_memset((PVOID)&fakeBTEfuseContent[i][0], 0xff, EFUSE_MAX_HW_SIZE);
++	}
++	_rtw_memset((PVOID)&fakeBTEfuseInitMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
++	_rtw_memset((PVOID)&fakeBTEfuseModifiedMap[0], 0xff, EFUSE_BT_MAX_MAP_LEN);
++}
++
++#ifdef PLATFORM_LINUX
++#ifdef CONFIG_ADAPTOR_INFO_CACHING_FILE
++//#include <rtw_eeprom.h>
++
++ int isAdaptorInfoFileValid(void)
++{
++	return _TRUE;
++}
++
++int storeAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv)
++{
++	int ret =_SUCCESS;
++
++	if(path && eeprom_priv) {
++		ret = rtw_store_to_file(path, eeprom_priv->efuse_eeprom_data, EEPROM_MAX_SIZE);
++		if(ret == EEPROM_MAX_SIZE)
++			ret = _SUCCESS;
++		else
++			ret = _FAIL;
++	} else {
++		DBG_871X("%s NULL pointer\n",__FUNCTION__);
++		ret =  _FAIL;
++	}
++	return ret;
++}
++
++int retriveAdaptorInfoFile(char *path, struct eeprom_priv * eeprom_priv)
++{
++	int ret = _SUCCESS;
++	mm_segment_t oldfs;
++	struct file *fp;
++
++	if(path && eeprom_priv) {
++
++		ret = rtw_retrive_from_file(path, eeprom_priv->efuse_eeprom_data, EEPROM_MAX_SIZE);
++
++		if(ret == EEPROM_MAX_SIZE)
++			ret = _SUCCESS;
++		else
++			ret = _FAIL;
++
++		#if 0
++		if(isAdaptorInfoFileValid()) {
++			return 0;
++		} else {
++			return _FAIL;
++		}
++		#endif
++
++	} else {
++		DBG_871X("%s NULL pointer\n",__FUNCTION__);
++		ret = _FAIL;
++	}
++	return ret;
++}
++#endif //CONFIG_ADAPTOR_INFO_CACHING_FILE
++#endif //PLATFORM_LINUX
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ap.c
+@@ -0,0 +1,2939 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_AP_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <wifi.h>
++
++
++#ifdef CONFIG_AP_MODE
++
++extern unsigned char	RTW_WPA_OUI[];
++extern unsigned char 	WMM_OUI[];
++extern unsigned char	WPS_OUI[];
++extern unsigned char	P2P_OUI[];
++extern unsigned char	WFD_OUI[];
++
++void init_mlme_ap_info(_adapter *padapter)
++{
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
++
++
++	_rtw_spinlock_init(&pmlmepriv->bcn_update_lock);
++
++	//for ACL
++	_rtw_init_queue(&pacl_list->acl_node_q);
++
++	//pmlmeext->bstart_bss = _FALSE;
++
++	start_ap_mode(padapter);
++}
++
++void free_mlme_ap_info(_adapter *padapter)
++{
++	_irqL irqL;
++	struct sta_info *psta=NULL;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	//stop_ap_mode(padapter);
++
++	pmlmepriv->update_bcn = _FALSE;
++	pmlmeext->bstart_bss = _FALSE;
++
++	rtw_sta_flush(padapter);
++
++	pmlmeinfo->state = _HW_STATE_NOLINK_;
++
++	//free_assoc_sta_resources
++	rtw_free_all_stainfo(padapter);
++
++	//free bc/mc sta_info
++	psta = rtw_get_bcmc_stainfo(padapter);
++	_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++	rtw_free_stainfo(padapter, psta);
++	_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++
++	_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
++
++}
++
++static void update_BCNTIM(_adapter *padapter)
++{
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
++	unsigned char *pie = pnetwork_mlmeext->IEs;
++
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	//update TIM IE
++	//if(pstapriv->tim_bitmap)
++	if(_TRUE)
++	{
++		u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
++		u16 tim_bitmap_le;
++		uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
++
++		tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
++
++		p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
++		if (p != NULL && tim_ielen>0)
++		{
++			tim_ielen += 2;
++
++			premainder_ie = p+tim_ielen;
++
++			tim_ie_offset = (sint)(p -pie);
++
++			remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
++
++			//append TIM IE from dst_ie offset
++			dst_ie = p;
++		}
++		else
++		{
++			tim_ielen = 0;
++
++			//calucate head_len
++			offset = _FIXED_IE_LENGTH_;
++
++			/* get ssid_ie len */
++			p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
++			if (p !=  NULL)
++				offset += tmp_len+2;
++
++			// get supported rates len
++			p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
++			if (p !=  NULL)
++			{
++				offset += tmp_len+2;
++			}
++
++			//DS Parameter Set IE, len=3
++			offset += 3;
++
++			premainder_ie = pie + offset;
++
++			remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
++
++			//append TIM IE from offset
++			dst_ie = pie + offset;
++
++		}
++
++
++		if(remainder_ielen>0)
++		{
++			pbackup_remainder_ie = rtw_malloc(remainder_ielen);
++			if(pbackup_remainder_ie && premainder_ie)
++				_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
++		}
++
++		*dst_ie++=_TIM_IE_;
++
++		if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
++			tim_ielen = 5;
++		else
++			tim_ielen = 4;
++
++		*dst_ie++= tim_ielen;
++
++		*dst_ie++=0;//DTIM count
++		*dst_ie++=1;//DTIM peroid
++
++		if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames
++			*dst_ie++ = BIT(0);//bitmap ctrl
++		else
++			*dst_ie++ = 0;
++
++		if(tim_ielen==4)
++		{
++			*dst_ie++ = *(u8*)&tim_bitmap_le;
++		}
++		else if(tim_ielen==5)
++		{
++			_rtw_memcpy(dst_ie, &tim_bitmap_le, 2);
++			dst_ie+=2;
++		}
++
++		//copy remainder IE
++		if(pbackup_remainder_ie)
++		{
++			_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
++
++			rtw_mfree(pbackup_remainder_ie, remainder_ielen);
++		}
++
++		offset =  (uint)(dst_ie - pie);
++		pnetwork_mlmeext->IELength = offset + remainder_ielen;
++
++	}
++
++#ifndef CONFIG_INTERRUPT_BASED_TXBCN
++#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
++	set_tx_beacon_cmd(padapter);
++#endif
++#endif //!CONFIG_INTERRUPT_BASED_TXBCN
++
++
++}
++
++void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)
++{
++	PNDIS_802_11_VARIABLE_IEs	pIE;
++	u8	bmatch = _FALSE;
++	u8	*pie = pnetwork->IEs;
++	u8	*p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
++	u32	i, offset, ielen, ie_offset, remainder_ielen = 0;
++
++	for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
++	{
++		pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
++
++		if (pIE->ElementID > index)
++		{
++			break;
++		}
++		else if(pIE->ElementID == index) // already exist the same IE
++		{
++			p = (u8 *)pIE;
++			ielen = pIE->Length;
++			bmatch = _TRUE;
++			break;
++		}
++
++		p = (u8 *)pIE;
++		ielen = pIE->Length;
++		i += (pIE->Length + 2);
++	}
++
++	if (p != NULL && ielen>0)
++	{
++		ielen += 2;
++
++		premainder_ie = p+ielen;
++
++		ie_offset = (sint)(p -pie);
++
++		remainder_ielen = pnetwork->IELength - ie_offset - ielen;
++
++		if(bmatch)
++			dst_ie = p;
++		else
++			dst_ie = (p+ielen);
++	}
++
++	if(remainder_ielen>0)
++	{
++		pbackup_remainder_ie = rtw_malloc(remainder_ielen);
++		if(pbackup_remainder_ie && premainder_ie)
++			_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
++	}
++
++	*dst_ie++=index;
++	*dst_ie++=len;
++
++	_rtw_memcpy(dst_ie, data, len);
++	dst_ie+=len;
++
++	//copy remainder IE
++	if(pbackup_remainder_ie)
++	{
++		_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
++
++		rtw_mfree(pbackup_remainder_ie, remainder_ielen);
++	}
++
++	offset =  (uint)(dst_ie - pie);
++	pnetwork->IELength = offset + remainder_ielen;
++}
++
++void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)
++{
++	u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
++	uint offset, ielen, ie_offset, remainder_ielen = 0;
++	u8	*pie = pnetwork->IEs;
++
++	p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);
++	if (p != NULL && ielen>0)
++	{
++		ielen += 2;
++
++		premainder_ie = p+ielen;
++
++		ie_offset = (sint)(p -pie);
++
++		remainder_ielen = pnetwork->IELength - ie_offset - ielen;
++
++		dst_ie = p;
++	}
++	else {
++		return;
++	}
++
++	if(remainder_ielen>0)
++	{
++		pbackup_remainder_ie = rtw_malloc(remainder_ielen);
++		if(pbackup_remainder_ie && premainder_ie)
++			_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
++	}
++
++	//copy remainder IE
++	if(pbackup_remainder_ie)
++	{
++		_rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
++
++		rtw_mfree(pbackup_remainder_ie, remainder_ielen);
++	}
++
++	offset =  (uint)(dst_ie - pie);
++	pnetwork->IELength = offset + remainder_ielen;
++}
++
++
++u8 chk_sta_is_alive(struct sta_info *psta);
++u8 chk_sta_is_alive(struct sta_info *psta)
++{
++	u8 ret = _FALSE;
++	#ifdef DBG_EXPIRATION_CHK
++	DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
++		, MAC_ARG(psta->hwaddr)
++		, psta->rssi_stat.UndecoratedSmoothedPWDB
++		//, STA_RX_PKTS_ARG(psta)
++		, STA_RX_PKTS_DIFF_ARG(psta)
++		, psta->expire_to
++		, psta->state&WIFI_SLEEP_STATE?"PS, ":""
++		, psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""
++		, psta->sleepq_len
++	);
++	#endif
++
++	//if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta))
++	if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
++	{
++		#if 0
++		if(psta->state&WIFI_SLEEP_STATE)
++			ret = _TRUE;
++		#endif
++	}
++	else
++	{
++		ret = _TRUE;
++	}
++
++	sta_update_last_rx_pkts(psta);
++
++	return ret;
++}
++
++void	expire_timeout_chk(_adapter *padapter)
++{
++	_irqL irqL;
++	_list	*phead, *plist;
++	u8 updated;
++	struct sta_info *psta=NULL;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	u8 chk_alive_num = 0;
++	char chk_alive_list[NUM_STA];
++	int i;
++
++	_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
++
++	phead = &pstapriv->auth_list;
++	plist = get_next(phead);
++
++	//check auth_queue
++	#ifdef DBG_EXPIRATION_CHK
++	if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
++		DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
++			, FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
++	}
++	#endif
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++	{
++		psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
++		plist = get_next(plist);
++
++		if(psta->expire_to>0)
++		{
++			psta->expire_to--;
++			if (psta->expire_to == 0)
++			{
++				rtw_list_delete(&psta->auth_list);
++				pstapriv->auth_list_cnt--;
++
++				DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n",
++					psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]);
++
++				_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
++
++				_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++				rtw_free_stainfo(padapter, psta);
++				_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++				_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
++			}
++		}
++
++	}
++
++	_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
++
++	psta = NULL;
++
++
++	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	phead = &pstapriv->asoc_list;
++	plist = get_next(phead);
++
++	//check asoc_queue
++	#ifdef DBG_EXPIRATION_CHK
++	if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
++		DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
++			, FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
++	}
++	#endif
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++	{
++		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
++		plist = get_next(plist);
++
++		if (chk_sta_is_alive(psta) || !psta->expire_to) {
++			psta->expire_to = pstapriv->expire_to;
++			psta->keep_alive_trycnt = 0;
++			#ifdef CONFIG_TX_MCAST2UNI
++			psta->under_exist_checking = 0;
++			#endif	// CONFIG_TX_MCAST2UNI
++		} else {
++			psta->expire_to--;
++		}
++
++#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++#ifdef CONFIG_TX_MCAST2UNI
++		if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) {
++			// check sta by delba(addba) for 11n STA
++			// ToDo: use CCX report to check for all STAs
++			//DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking);
++
++			if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) {
++				DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
++				psta->under_exist_checking = 0;
++				psta->expire_to = 0;
++			} else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) {
++				DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
++				psta->under_exist_checking = 1;
++				//tear down TX AMPDU
++				send_delba(padapter, 1, psta->hwaddr);// // originator
++				psta->htpriv.agg_enable_bitmap = 0x0;//reset
++				psta->htpriv.candidate_tid_bitmap = 0x0;//reset
++			}
++		}
++#endif // CONFIG_TX_MCAST2UNI
++#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++
++		if (psta->expire_to <= 0)
++		{
++			#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++			struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++
++			if (padapter->registrypriv.wifi_spec == 1)
++			{
++				psta->expire_to = pstapriv->expire_to;
++				continue;
++			}
++
++			if (psta->state & WIFI_SLEEP_STATE) {
++				if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
++					//to check if alive by another methods if staion is at ps mode.
++					psta->expire_to = pstapriv->expire_to;
++					psta->state |= WIFI_STA_ALIVE_CHK_STATE;
++
++					//DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr));
++
++					//to update bcn with tim_bitmap for this station
++					pstapriv->tim_bitmap |= BIT(psta->aid);
++					update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
++
++					if(!pmlmeext->active_keep_alive_check)
++						continue;
++				}
++			}
++
++			if (pmlmeext->active_keep_alive_check) {
++				int stainfo_offset;
++
++				stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
++				if (stainfo_offset_valid(stainfo_offset)) {
++					chk_alive_list[chk_alive_num++] = stainfo_offset;
++				}
++
++				continue;
++			}
++			#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
++
++			rtw_list_delete(&psta->asoc_list);
++			pstapriv->asoc_list_cnt--;
++
++			DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
++			updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
++		}
++		else
++		{
++			/* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
++			if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
++				&& padapter->xmitpriv.free_xmitframe_cnt < (NR_XMITFRAME/pstapriv->asoc_list_cnt/2)
++			){
++				DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__
++					, MAC_ARG(psta->hwaddr)
++					, psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);
++				wakeup_sta_to_xmit(padapter, psta);
++			}
++		}
++	}
++
++	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++if (chk_alive_num) {
++
++	u8 backup_oper_channel=0;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	/* switch to correct channel of current network  before issue keep-alive frames */
++	if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
++		backup_oper_channel = rtw_get_oper_ch(padapter);
++		SelectChannel(padapter, pmlmeext->cur_channel);
++	}
++
++	/* issue null data to check sta alive*/
++	for (i = 0; i < chk_alive_num; i++) {
++
++		int ret = _FAIL;
++
++		psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
++		if(!(psta->state &_FW_LINKED))
++			continue;
++
++		if (psta->state & WIFI_SLEEP_STATE)
++			ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
++		else
++			ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
++
++		psta->keep_alive_trycnt++;
++		if (ret == _SUCCESS)
++		{
++			DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));
++			psta->expire_to = pstapriv->expire_to;
++			psta->keep_alive_trycnt = 0;
++			continue;
++		}
++		else if (psta->keep_alive_trycnt <= 3)
++		{
++			DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
++			psta->expire_to = 1;
++			continue;
++		}
++
++		psta->keep_alive_trycnt = 0;
++
++		DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
++		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++		if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {
++			rtw_list_delete(&psta->asoc_list);
++			pstapriv->asoc_list_cnt--;
++			updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
++		}
++		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	}
++
++	if (backup_oper_channel>0) /* back to the original operation channel */
++		SelectChannel(padapter, backup_oper_channel);
++}
++#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
++
++	associated_clients_update(padapter, updated);
++}
++
++
++static void add_RATid(_adapter *padapter, struct sta_info *psta)
++{
++	int i;
++	u8 rf_type;
++	u32 init_rate=0;
++	unsigned char sta_band = 0, raid, shortGIrate = _FALSE;
++	unsigned char limit;
++	unsigned int tx_ra_bitmap=0;
++	struct ht_priv	*psta_ht = NULL;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
++
++
++	if(psta)
++		psta_ht = &psta->htpriv;
++	else
++		return;
++
++	//b/g mode ra_bitmap
++	for (i=0; i<sizeof(psta->bssrateset); i++)
++	{
++		if (psta->bssrateset[i])
++			tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
++	}
++
++	//n mode ra_bitmap
++	if(psta_ht->ht_option)
++	{
++		rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
++		if(rf_type == RF_2T2R)
++			limit=16;// 2R
++		else
++			limit=8;//  1R
++
++		for (i=0; i<limit; i++) {
++			if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
++				tx_ra_bitmap |= BIT(i+12);
++		}
++
++		//max short GI rate
++		shortGIrate = psta_ht->sgi;
++	}
++
++
++#if 0//gtest
++	if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)
++	{
++		//is this a 2r STA?
++		if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid)))
++		{
++			priv->pshare->has_2r_sta |= BIT(pstat->aid);
++			if(rtw_read16(padapter, 0x102501f6) != 0xffff)
++			{
++				rtw_write16(padapter, 0x102501f6, 0xffff);
++				reset_1r_sta_RA(priv, 0xffff);
++				Switch_1SS_Antenna(priv, 3);
++			}
++		}
++		else// bg or 1R STA?
++		{
++			if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0)
++			{
++				if(rtw_read16(padapter, 0x102501f6) != 0x7777)
++				{ // MCS7 SGI
++					rtw_write16(padapter, 0x102501f6,0x7777);
++					reset_1r_sta_RA(priv, 0x7777);
++					Switch_1SS_Antenna(priv, 2);
++				}
++			}
++		}
++
++	}
++
++	if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3))
++	{
++		if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper)
++			pstat->rssi_level = 1;
++		else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) ||
++			((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) &&
++			(pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) &&
++			(pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_))))
++			pstat->rssi_level = 2;
++		else
++			pstat->rssi_level = 3;
++	}
++
++	// rate adaptive by rssi
++	if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len)
++	{
++		if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R))
++		{
++			switch (pstat->rssi_level) {
++				case 1:
++					pstat->tx_ra_bitmap &= 0x100f0000;
++					break;
++				case 2:
++					pstat->tx_ra_bitmap &= 0x100ff000;
++					break;
++				case 3:
++					if (priv->pshare->is_40m_bw)
++						pstat->tx_ra_bitmap &= 0x100ff005;
++					else
++						pstat->tx_ra_bitmap &= 0x100ff001;
++
++					break;
++			}
++		}
++		else
++		{
++			switch (pstat->rssi_level) {
++				case 1:
++					pstat->tx_ra_bitmap &= 0x1f0f0000;
++					break;
++				case 2:
++					pstat->tx_ra_bitmap &= 0x1f0ff000;
++					break;
++				case 3:
++					if (priv->pshare->is_40m_bw)
++						pstat->tx_ra_bitmap &= 0x000ff005;
++					else
++						pstat->tx_ra_bitmap &= 0x000ff001;
++
++					break;
++			}
++
++			// Don't need to mask high rates due to new rate adaptive parameters
++			//if (pstat->is_broadcom_sta)		// use MCS12 as the highest rate vs. Broadcom sta
++			//	pstat->tx_ra_bitmap &= 0x81ffffff;
++
++			// NIC driver will report not supporting MCS15 and MCS14 in asoc req
++			//if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta)
++			//	pstat->tx_ra_bitmap &= 0x83ffffff;		// if Realtek 1x2 sta, don't use MCS15 and MCS14
++		}
++	}
++	else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat))
++	{
++		switch (pstat->rssi_level) {
++			case 1:
++				pstat->tx_ra_bitmap &= 0x00000f00;
++				break;
++			case 2:
++				pstat->tx_ra_bitmap &= 0x00000ff0;
++				break;
++			case 3:
++				pstat->tx_ra_bitmap &= 0x00000ff5;
++				break;
++		}
++	}
++	else
++	{
++		pstat->tx_ra_bitmap &= 0x0000000d;
++	}
++
++	// disable tx short GI when station cannot rx MCS15(AP is 2T2R)
++	// disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R)
++	// if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate
++	if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) ||
++		 (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R)))
++	{
++		pstat->tx_ra_bitmap &= ~BIT(28);
++	}
++#endif
++
++	if ( pcur_network->Configuration.DSConfig > 14 ) {
++		// 5G band
++		if (tx_ra_bitmap & 0xffff000)
++			sta_band |= WIRELESS_11_5N | WIRELESS_11A;
++		else
++			sta_band |= WIRELESS_11A;
++	} else {
++		if (tx_ra_bitmap & 0xffff000)
++			sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
++		else if (tx_ra_bitmap & 0xff0)
++			sta_band |= WIRELESS_11G |WIRELESS_11B;
++		else
++			sta_band |= WIRELESS_11B;
++	}
++
++	raid = networktype_to_raid(sta_band);
++	init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
++
++	if (psta->aid < NUM_STA)
++	{
++		u8 arg = 0;
++
++		arg = psta->mac_id&0x1f;
++
++		arg |= BIT(7);//support entry 2~31
++
++		if (shortGIrate==_TRUE)
++			arg |= BIT(5);
++
++		tx_ra_bitmap |= ((raid<<28)&0xf0000000);
++
++		DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x, arg=0x%x\n",
++			__FUNCTION__ , psta->mac_id, raid ,tx_ra_bitmap, arg);
++
++		//bitmap[0:27] = tx_rate_bitmap
++		//bitmap[28:31]= Rate Adaptive id
++		//arg[0:4] = macid
++		//arg[5] = Short GI
++		rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg);
++
++		if (shortGIrate==_TRUE)
++			init_rate |= BIT(6);
++
++		//set ra_id, init_rate
++		psta->raid = raid;
++		psta->init_rate = init_rate;
++
++	}
++	else
++	{
++		DBG_871X("station aid %d exceed the max number\n", psta->aid);
++	}
++
++}
++
++static void update_bmc_sta(_adapter *padapter)
++{
++	_irqL	irqL;
++	u32 init_rate=0;
++	unsigned char	network_type, raid;
++	int i, supportRateNum = 0;
++	unsigned int tx_ra_bitmap=0;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
++	struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
++
++	if(psta)
++	{
++		psta->aid = 0;//default set to 0
++		//psta->mac_id = psta->aid+4;
++		psta->mac_id = psta->aid + 1;
++
++		psta->qos_option = 0;
++		psta->htpriv.ht_option = _FALSE;
++
++		psta->ieee8021x_blocked = 0;
++
++		_rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
++
++		//psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this.
++
++
++
++		//prepare for add_RATid
++		supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates);
++		network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, 1);
++
++		_rtw_memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
++		psta->bssratelen = supportRateNum;
++
++		//b/g mode ra_bitmap
++		for (i=0; i<supportRateNum; i++)
++		{
++			if (psta->bssrateset[i])
++				tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
++		}
++
++		if ( pcur_network->Configuration.DSConfig > 14 ) {
++			//force to A mode. 5G doesn't support CCK rates
++			network_type = WIRELESS_11A;
++			tx_ra_bitmap = 0x150; // 6, 12, 24 Mbps
++		} else {
++			//force to b mode
++			network_type = WIRELESS_11B;
++			tx_ra_bitmap = 0xf;
++		}
++
++		//tx_ra_bitmap = update_basic_rate(pcur_network->SupportedRates, supportRateNum);
++
++		raid = networktype_to_raid(network_type);
++		init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
++
++		//DBG_871X("Add id %d val %08x to ratr for bmc sta\n", psta->aid, tx_ra_bitmap);
++
++		//if(pHalData->fw_ractrl == _TRUE)
++		{
++			u8 arg = 0;
++
++			arg = psta->mac_id&0x1f;
++
++			arg |= BIT(7);
++
++			//if (shortGIrate==_TRUE)
++			//	arg |= BIT(5);
++
++			tx_ra_bitmap |= ((raid<<28)&0xf0000000);
++
++			DBG_871X("update_bmc_sta, mask=0x%x, arg=0x%x\n", tx_ra_bitmap, arg);
++
++			//bitmap[0:27] = tx_rate_bitmap
++			//bitmap[28:31]= Rate Adaptive id
++			//arg[0:4] = macid
++			//arg[5] = Short GI
++			rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg);
++
++		}
++
++		//set ra_id, init_rate
++		psta->raid = raid;
++		psta->init_rate = init_rate;
++
++		_enter_critical_bh(&psta->lock, &irqL);
++		psta->state = _FW_LINKED;
++		_exit_critical_bh(&psta->lock, &irqL);
++
++	}
++	else
++	{
++		DBG_871X("add_RATid_bmc_sta error!\n");
++	}
++
++}
++
++//notes:
++//AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode
++//MAC_ID = AID+1 for sta in ap/adhoc mode
++//MAC_ID = 1 for bc/mc for sta/ap/adhoc
++//MAC_ID = 0 for bssid for sta/ap/adhoc
++//CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1;
++
++void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)
++{
++	_irqL	irqL;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct security_priv *psecuritypriv = &padapter->securitypriv;
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct ht_priv	*phtpriv_ap = &pmlmepriv->htpriv;
++	struct ht_priv	*phtpriv_sta = &psta->htpriv;
++
++	//set intf_tag to if1
++	//psta->intf_tag = 0;
++
++	//psta->mac_id = psta->aid+4;
++	psta->mac_id = psta->aid+1;
++
++	if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
++		psta->ieee8021x_blocked = _TRUE;
++	else
++		psta->ieee8021x_blocked = _FALSE;
++
++
++	//update sta's cap
++
++	//ERP
++	VCS_update(padapter, psta);
++
++	//HT related cap
++	if(phtpriv_sta->ht_option)
++	{
++		//check if sta supports rx ampdu
++		phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
++
++		//check if sta support s Short GI
++		if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
++		{
++			phtpriv_sta->sgi = _TRUE;
++		}
++
++		// bwmode
++		if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
++		{
++			//phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40;
++			phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
++			phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
++
++		}
++
++		psta->qos_option = _TRUE;
++
++	}
++	else
++	{
++		phtpriv_sta->ampdu_enable = _FALSE;
++
++		phtpriv_sta->sgi = _FALSE;
++		phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
++		phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++	}
++
++	//Rx AMPDU
++	send_delba(padapter, 0, psta->hwaddr);// recipient
++
++	//TX AMPDU
++	send_delba(padapter, 1, psta->hwaddr);// // originator
++	phtpriv_sta->agg_enable_bitmap = 0x0;//reset
++	phtpriv_sta->candidate_tid_bitmap = 0x0;//reset
++
++
++	//todo: init other variables
++
++	_rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
++
++
++	//add ratid
++	//add_RATid(padapter, psta);//move to ap_sta_info_defer_update()
++
++
++	_enter_critical_bh(&psta->lock, &irqL);
++	psta->state |= _FW_LINKED;
++	_exit_critical_bh(&psta->lock, &irqL);
++
++
++}
++
++static void update_hw_ht_param(_adapter *padapter)
++{
++	unsigned char		max_AMPDU_len;
++	unsigned char		min_MPDU_spacing;
++	struct registry_priv	 *pregpriv = &padapter->registrypriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++
++	//handle A-MPDU parameter field
++	/*
++		AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
++		AMPDU_para [4:2]:Min MPDU Start Spacing
++	*/
++	max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
++
++	min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
++
++	rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
++
++	rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
++
++	//
++	// Config SM Power Save setting
++	//
++	pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
++	if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
++	{
++		/*u8 i;
++		//update the MCS rates
++		for (i = 0; i < 16; i++)
++		{
++			pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
++		}*/
++		DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
++	}
++
++	//
++	// Config current HT Protection mode.
++	//
++	//pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
++
++}
++
++static void start_bss_network(_adapter *padapter, u8 *pbuf)
++{
++	u8 *p;
++	u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
++	u16 bcn_interval;
++	u32	acparm;
++	int	ie_len;
++	struct registry_priv	 *pregpriv = &padapter->registrypriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct security_priv* psecuritypriv=&(padapter->securitypriv);
++	WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
++	struct HT_info_element *pht_info=NULL;
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++#endif //CONFIG_P2P
++	u8 cbw40_enable=0;
++	u8 change_band = _FALSE;
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
++	cur_channel = pnetwork->Configuration.DSConfig;
++	cur_bwmode = HT_CHANNEL_WIDTH_20;;
++	cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++
++
++	//check if there is wps ie,
++	//if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd,
++	//and at first time the security ie ( RSN/WPA IE) will not include in beacon.
++	if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
++	{
++		pmlmeext->bstart_bss = _TRUE;
++	}
++
++	//todo: update wmm, ht cap
++	//pmlmeinfo->WMM_enable;
++	//pmlmeinfo->HT_enable;
++	if(pmlmepriv->qospriv.qos_option)
++		pmlmeinfo->WMM_enable = _TRUE;
++
++	if(pmlmepriv->htpriv.ht_option)
++	{
++		pmlmeinfo->WMM_enable = _TRUE;
++		pmlmeinfo->HT_enable = _TRUE;
++		//pmlmeinfo->HT_info_enable = _TRUE;
++		//pmlmeinfo->HT_caps_enable = _TRUE;
++
++		update_hw_ht_param(padapter);
++	}
++
++
++	if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at  first time
++	{
++		//WEP Key will be set before this function, do not clear CAM.
++		if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
++			flush_all_cam_entry(padapter);	//clear CAM
++	}
++
++	//set MSR to AP_Mode
++	Set_MSR(padapter, _HW_STATE_AP_);
++
++	//Set BSSID REG
++	rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
++
++	//Set EDCA param reg
++#ifdef CONFIG_CONCURRENT_MODE
++	acparm = 0x005ea42b;
++#else
++	acparm = 0x002F3217; // VO
++#endif
++	rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
++	acparm = 0x005E4317; // VI
++	rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
++	//acparm = 0x00105320; // BE
++	acparm = 0x005ea42b;
++	rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
++	acparm = 0x0000A444; // BK
++	rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
++
++	//Set Security
++	val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
++	rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
++
++	//Beacon Control related register
++	rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
++
++	if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at  first time
++	{
++		u32 initialgain;
++
++		initialgain = 0x1e;
++
++
++		//disable dynamic functions, such as high power, DIG
++		//Save_DM_Func_Flag(padapter);
++		//Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
++
++#ifdef CONFIG_CONCURRENT_MODE
++		if(padapter->adapter_type > PRIMARY_ADAPTER)
++		{
++			if(rtw_buddy_adapter_up(padapter))
++			{
++				_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++
++				//turn on dynamic functions on PRIMARY_ADAPTER, dynamic functions only runs at PRIMARY_ADAPTER
++				Switch_DM_Func(pbuddy_adapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE);
++
++				rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
++			}
++		}
++		else
++#endif
++		{
++			//turn on dynamic functions
++			Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE);
++
++			rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
++		}
++
++	}
++
++	//set channel, bwmode
++	p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
++	if( p && ie_len)
++	{
++		pht_info = (struct HT_info_element *)(p+2);
++
++		if( pmlmeext->cur_channel > 14 )
++		{
++			if( pregpriv->cbw40_enable & BIT(1) )
++				cbw40_enable = 1;
++		}
++		else
++			if( pregpriv->cbw40_enable & BIT(0) )
++				cbw40_enable = 1;
++
++		if ((cbw40_enable) &&	 (pht_info->infos[0] & BIT(2)))
++		{
++			//switch to the 40M Hz mode
++			//pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
++			cur_bwmode = HT_CHANNEL_WIDTH_40;
++			switch (pht_info->infos[0] & 0x3)
++			{
++				case 1:
++					//pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
++					cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
++					break;
++
++				case 3:
++					//pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
++					cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
++					break;
++
++				default:
++					//pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++					cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++					break;
++			}
++
++		}
++
++	}
++
++#ifdef CONFIG_DUALMAC_CONCURRENT
++	dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);
++#else
++	//TODO: need to judge the phy parameters on concurrent mode for single phy
++	//set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
++#ifdef CONFIG_CONCURRENT_MODE
++	if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
++	{
++		set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
++	}
++	else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)//only second adapter can enter AP Mode
++	{
++		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++		struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++
++		//To sync cur_channel/cur_bwmode/cur_ch_offset with primary adapter
++		DBG_871X("primary iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
++		DBG_871X("primary adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
++		DBG_871X("second adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
++
++		if((cur_channel <= 14 && pbuddy_mlmeext->cur_channel >= 36) ||
++		(cur_channel >= 36 && pbuddy_mlmeext->cur_channel <= 14))
++			change_band = _TRUE;
++
++		cur_channel = pbuddy_mlmeext->cur_channel;
++		if(cur_bwmode == HT_CHANNEL_WIDTH_40)
++		{
++			if(pht_info)
++				pht_info->infos[0] &= ~(BIT(0)|BIT(1));
++
++			if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
++			{
++				cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
++
++				//to update cur_ch_offset value in beacon
++				if(pht_info)
++				{
++					switch(cur_ch_offset)
++					{
++						case HAL_PRIME_CHNL_OFFSET_LOWER:
++							pht_info->infos[0] |= 0x1;
++							break;
++						case HAL_PRIME_CHNL_OFFSET_UPPER:
++							pht_info->infos[0] |= 0x3;
++							break;
++						case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
++						default:
++							break;
++					}
++				}
++
++			}
++			else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
++			{
++				cur_bwmode = HT_CHANNEL_WIDTH_20;
++				cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++
++				if(cur_channel>0 && cur_channel<5)
++				{
++					if(pht_info)
++						pht_info->infos[0] |= 0x1;
++
++					cur_bwmode = HT_CHANNEL_WIDTH_40;
++					cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
++				}
++
++				if(cur_channel>7 && cur_channel<(14+1))
++				{
++					if(pht_info)
++						pht_info->infos[0] |= 0x3;
++
++					cur_bwmode = HT_CHANNEL_WIDTH_40;
++					cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
++				}
++
++				set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
++			}
++
++		}
++
++		// to update channel value in beacon
++		pnetwork->Configuration.DSConfig = cur_channel;
++		p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
++		if(p && ie_len>0)
++			*(p + 2) = cur_channel;
++
++		if(pht_info)
++			pht_info->primary_channel = cur_channel;
++
++		//set buddy adapter channel, bandwidth, offeset to current adapter
++		pmlmeext->cur_channel = cur_channel;
++		pmlmeext->cur_bwmode = cur_bwmode;
++		pmlmeext->cur_ch_offset = cur_ch_offset;
++
++		//buddy interface band is different from current interface, update ERP, support rate, ext support rate IE
++		if(change_band == _TRUE)
++			change_band_update_ie(padapter, pnetwork);
++	}
++#else
++	set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
++#endif //CONFIG_CONCURRENT_MODE
++
++	DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
++
++	//
++	pmlmeext->cur_channel = cur_channel;
++	pmlmeext->cur_bwmode = cur_bwmode;
++	pmlmeext->cur_ch_offset = cur_ch_offset;
++#endif //CONFIG_DUALMAC_CONCURRENT
++	pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
++
++	//update cur_wireless_mode
++	update_wireless_mode(padapter);
++
++	//update RRSR after set channel and bandwidth
++	UpdateBrateTbl(padapter, pnetwork->SupportedRates);
++	rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
++
++	//udpate capability after cur_wireless_mode updated
++	update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));
++
++	//let pnetwork_mlmeext == pnetwork_mlme.
++	_rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
++
++#ifdef CONFIG_P2P
++	_rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);
++	pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;
++#endif //CONFIG_P2P
++
++	if(_TRUE == pmlmeext->bstart_bss)
++	{
++		update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
++
++#ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will  tx beacon when bcn interrupt coming in.
++#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
++		//issue beacon frame
++		if(send_beacon(padapter)==_FAIL)
++		{
++			DBG_871X("issue_beacon, fail!\n");
++		}
++#endif
++#endif //!CONFIG_INTERRUPT_BASED_TXBCN
++
++	}
++
++
++	//update bc/mc sta_info
++	update_bmc_sta(padapter);
++
++	//pmlmeext->bstart_bss = _TRUE;
++
++}
++
++int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf,  int len)
++{
++	int ret=_SUCCESS;
++	u8 *p;
++	u8 *pHT_caps_ie=NULL;
++	u8 *pHT_info_ie=NULL;
++	struct sta_info *psta = NULL;
++	u16 cap, ht_cap=_FALSE;
++	uint ie_len = 0;
++	int group_cipher, pairwise_cipher;
++	u8	channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
++	int supportRateNum = 0;
++	u8 OUI1[] = {0x00, 0x50, 0xf2,0x01};
++	u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
++	u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
++	struct registry_priv *pregistrypriv = &padapter->registrypriv;
++	struct security_priv *psecuritypriv = &padapter->securitypriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	u8 *ie = pbss_network->IEs;
++
++
++	/* SSID */
++	/* Supported rates */
++	/* DS Params */
++	/* WLAN_EID_COUNTRY */
++	/* ERP Information element */
++	/* Extended supported rates */
++	/* WPA/WPA2 */
++	/* Wi-Fi Wireless Multimedia Extensions */
++	/* ht_capab, ht_oper */
++	/* WPS IE */
++
++	DBG_871X("%s, len=%d\n", __FUNCTION__, len);
++
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
++		return _FAIL;
++
++
++	if(len>MAX_IE_SZ)
++		return _FAIL;
++
++	pbss_network->IELength = len;
++
++	_rtw_memset(ie, 0, MAX_IE_SZ);
++
++	_rtw_memcpy(ie, pbuf, pbss_network->IELength);
++
++
++	if(pbss_network->InfrastructureMode!=Ndis802_11APMode)
++		return _FAIL;
++
++	pbss_network->Rssi = 0;
++
++	_rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
++
++	//beacon interval
++	p = rtw_get_beacon_interval_from_ie(ie);//ie + 8;	// 8: TimeStamp, 2: Beacon Interval 2:Capability
++	//pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p);
++	pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
++
++	//capability
++	//cap = *(unsigned short *)rtw_get_capability_from_ie(ie);
++	//cap = le16_to_cpu(cap);
++	cap = RTW_GET_LE16(ie);
++
++	//SSID
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_));
++	if(p && ie_len>0)
++	{
++		_rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
++		_rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
++		pbss_network->Ssid.SsidLength = ie_len;
++	}
++
++	//chnnel
++	channel = 0;
++	pbss_network->Configuration.Length = 0;
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
++	if(p && ie_len>0)
++		channel = *(p + 2);
++
++	pbss_network->Configuration.DSConfig = channel;
++
++
++	_rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
++	// get supported rates
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
++	if (p !=  NULL)
++	{
++		_rtw_memcpy(supportRate, p+2, ie_len);
++		supportRateNum = ie_len;
++	}
++
++	//get ext_supported rates
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
++	if (p !=  NULL)
++	{
++		_rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
++		supportRateNum += ie_len;
++
++	}
++
++	network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
++
++	rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
++
++
++	//parsing ERP_IE
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
++	if(p && ie_len>0)
++	{
++		ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
++	}
++
++	//update privacy/security
++	if (cap & BIT(4))
++		pbss_network->Privacy = 1;
++	else
++		pbss_network->Privacy = 0;
++
++	psecuritypriv->wpa_psk = 0;
++
++	//wpa2
++	group_cipher = 0; pairwise_cipher = 0;
++	psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
++	psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
++	if(p && ie_len>0)
++	{
++		if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
++		{
++			psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
++
++			psecuritypriv->dot8021xalg = 1;//psk,  todo:802.1x
++			psecuritypriv->wpa_psk |= BIT(1);
++
++			psecuritypriv->wpa2_group_cipher = group_cipher;
++			psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
++#if 0
++			switch(group_cipher)
++			{
++				case WPA_CIPHER_NONE:
++				psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
++				break;
++				case WPA_CIPHER_WEP40:
++				psecuritypriv->wpa2_group_cipher = _WEP40_;
++				break;
++				case WPA_CIPHER_TKIP:
++				psecuritypriv->wpa2_group_cipher = _TKIP_;
++				break;
++				case WPA_CIPHER_CCMP:
++				psecuritypriv->wpa2_group_cipher = _AES_;
++				break;
++				case WPA_CIPHER_WEP104:
++				psecuritypriv->wpa2_group_cipher = _WEP104_;
++				break;
++			}
++
++			switch(pairwise_cipher)
++			{
++				case WPA_CIPHER_NONE:
++				psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
++				break;
++				case WPA_CIPHER_WEP40:
++				psecuritypriv->wpa2_pairwise_cipher = _WEP40_;
++				break;
++				case WPA_CIPHER_TKIP:
++				psecuritypriv->wpa2_pairwise_cipher = _TKIP_;
++				break;
++				case WPA_CIPHER_CCMP:
++				psecuritypriv->wpa2_pairwise_cipher = _AES_;
++				break;
++				case WPA_CIPHER_WEP104:
++				psecuritypriv->wpa2_pairwise_cipher = _WEP104_;
++				break;
++			}
++#endif
++		}
++
++	}
++
++	//wpa
++	ie_len = 0;
++	group_cipher = 0; pairwise_cipher = 0;
++	psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
++	psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
++	for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
++	{
++		p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
++		if ((p) && (_rtw_memcmp(p+2, OUI1, 4)))
++		{
++			if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
++			{
++				psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
++
++				psecuritypriv->dot8021xalg = 1;//psk,  todo:802.1x
++
++				psecuritypriv->wpa_psk |= BIT(0);
++
++				psecuritypriv->wpa_group_cipher = group_cipher;
++				psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
++
++#if 0
++				switch(group_cipher)
++				{
++					case WPA_CIPHER_NONE:
++					psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
++					break;
++					case WPA_CIPHER_WEP40:
++					psecuritypriv->wpa_group_cipher = _WEP40_;
++					break;
++					case WPA_CIPHER_TKIP:
++					psecuritypriv->wpa_group_cipher = _TKIP_;
++					break;
++					case WPA_CIPHER_CCMP:
++					psecuritypriv->wpa_group_cipher = _AES_;
++					break;
++					case WPA_CIPHER_WEP104:
++					psecuritypriv->wpa_group_cipher = _WEP104_;
++					break;
++				}
++
++				switch(pairwise_cipher)
++				{
++					case WPA_CIPHER_NONE:
++					psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
++					break;
++					case WPA_CIPHER_WEP40:
++					psecuritypriv->wpa_pairwise_cipher = _WEP40_;
++					break;
++					case WPA_CIPHER_TKIP:
++					psecuritypriv->wpa_pairwise_cipher = _TKIP_;
++					break;
++					case WPA_CIPHER_CCMP:
++					psecuritypriv->wpa_pairwise_cipher = _AES_;
++					break;
++					case WPA_CIPHER_WEP104:
++					psecuritypriv->wpa_pairwise_cipher = _WEP104_;
++					break;
++				}
++#endif
++			}
++
++			break;
++
++		}
++
++		if ((p == NULL) || (ie_len == 0))
++		{
++				break;
++		}
++
++	}
++
++	//wmm
++	ie_len = 0;
++	pmlmepriv->qospriv.qos_option = 0;
++	if(pregistrypriv->wmm_enable)
++	{
++		for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
++		{
++			p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
++			if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6))
++			{
++				pmlmepriv->qospriv.qos_option = 1;
++
++				*(p+8) |= BIT(7);//QoS Info, support U-APSD
++
++				/* disable all ACM bits since the WMM admission control is not supported */
++				*(p + 10) &= ~BIT(4); /* BE */
++				*(p + 14) &= ~BIT(4); /* BK */
++				*(p + 18) &= ~BIT(4); /* VI */
++				*(p + 22) &= ~BIT(4); /* VO */
++
++				break;
++			}
++
++			if ((p == NULL) || (ie_len == 0))
++			{
++				break;
++			}
++		}
++	}
++
++	//parsing HT_CAP_IE
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
++	if(p && ie_len>0)
++	{
++		u8 rf_type;
++
++		struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
++
++		pHT_caps_ie=p;
++
++
++		ht_cap = _TRUE;
++		network_type |= WIRELESS_11_24N;
++
++
++		rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
++
++		if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
++			(psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
++		{
++			pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
++		}
++		else
++		{
++			pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
++		}
++
++		pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); //set  Max Rx AMPDU size  to 64K
++
++		if(rf_type == RF_1T1R)
++		{
++			pht_cap->supp_mcs_set[0] = 0xff;
++			pht_cap->supp_mcs_set[1] = 0x0;
++		}
++
++		_rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
++
++	}
++
++	//parsing HT_INFO_IE
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
++	if(p && ie_len>0)
++	{
++		pHT_info_ie=p;
++	}
++
++	switch(network_type)
++	{
++		case WIRELESS_11B:
++			pbss_network->NetworkTypeInUse = Ndis802_11DS;
++			break;
++		case WIRELESS_11G:
++		case WIRELESS_11BG:
++             case WIRELESS_11G_24N:
++		case WIRELESS_11BG_24N:
++			pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
++			break;
++		case WIRELESS_11A:
++			pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
++			break;
++		default :
++			pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
++			break;
++	}
++
++	pmlmepriv->cur_network.network_type = network_type;
++
++
++	pmlmepriv->htpriv.ht_option = _FALSE;
++#ifdef CONFIG_80211N_HT
++	if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
++		      (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP))
++	{
++		//todo:
++		//ht_cap = _FALSE;
++	}
++
++	//ht_cap
++	if(pregistrypriv->ht_enable && ht_cap==_TRUE)
++	{
++		pmlmepriv->htpriv.ht_option = _TRUE;
++		pmlmepriv->qospriv.qos_option = 1;
++
++		if(pregistrypriv->ampdu_enable==1)
++		{
++			pmlmepriv->htpriv.ampdu_enable = _TRUE;
++		}
++
++		HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);
++
++		HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);
++	}
++#endif
++
++
++	pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX  *)pbss_network);
++
++	//issue beacon to start bss network
++	start_bss_network(padapter, (u8*)pbss_network);
++
++
++	//alloc sta_info for ap itself
++	psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
++	if(!psta)
++	{
++		psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
++		if (psta == NULL)
++		{
++			return _FAIL;
++		}
++	}
++	psta->state |= WIFI_AP_STATE;		//Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724
++	rtw_indicate_connect( padapter);
++
++	pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon
++
++	//update bc/mc sta_info
++	//update_bmc_sta(padapter);
++
++	return ret;
++
++}
++
++void rtw_set_macaddr_acl(_adapter *padapter, int mode)
++{
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
++
++	DBG_871X("%s, mode=%d\n", __func__, mode);
++
++	pacl_list->mode = mode;
++}
++
++int rtw_acl_add_sta(_adapter *padapter, u8 *addr)
++{
++	_irqL irqL;
++	_list	*plist, *phead;
++	u8 added = _FALSE;
++	int i, ret=0;
++	struct rtw_wlan_acl_node *paclnode;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
++	_queue	*pacl_node_q =&pacl_list->acl_node_q;
++
++	DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
++
++	if((NUM_ACL-1) < pacl_list->num)
++		return (-1);
++
++
++	_enter_critical_bh(&(pacl_node_q->lock), &irqL);
++
++	phead = get_list_head(pacl_node_q);
++	plist = get_next(phead);
++
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++	{
++		paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
++		plist = get_next(plist);
++
++		if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
++		{
++			if(paclnode->valid == _TRUE)
++			{
++				added = _TRUE;
++				DBG_871X("%s, sta has been added\n", __func__);
++				break;
++			}
++		}
++	}
++
++	_exit_critical_bh(&(pacl_node_q->lock), &irqL);
++
++
++	if(added == _TRUE)
++		return ret;
++
++
++	_enter_critical_bh(&(pacl_node_q->lock), &irqL);
++
++	for(i=0; i< NUM_ACL; i++)
++	{
++		paclnode = &pacl_list->aclnode[i];
++
++		if(paclnode->valid == _FALSE)
++		{
++			_rtw_init_listhead(&paclnode->list);
++
++			_rtw_memcpy(paclnode->addr, addr, ETH_ALEN);
++
++			paclnode->valid = _TRUE;
++
++			rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));
++
++			pacl_list->num++;
++
++			break;
++		}
++	}
++
++	DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
++
++	_exit_critical_bh(&(pacl_node_q->lock), &irqL);
++
++	return ret;
++}
++
++int rtw_acl_remove_sta(_adapter *padapter, u8 *addr)
++{
++	_irqL irqL;
++	_list	*plist, *phead;
++	int i, ret=0;
++	struct rtw_wlan_acl_node *paclnode;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
++	_queue	*pacl_node_q =&pacl_list->acl_node_q;
++
++	DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
++
++	_enter_critical_bh(&(pacl_node_q->lock), &irqL);
++
++	phead = get_list_head(pacl_node_q);
++	plist = get_next(phead);
++
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++	{
++		paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
++		plist = get_next(plist);
++
++		if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
++		{
++			if(paclnode->valid == _TRUE)
++			{
++				paclnode->valid = _FALSE;
++
++				rtw_list_delete(&paclnode->list);
++
++				pacl_list->num--;
++			}
++		}
++	}
++
++	_exit_critical_bh(&(pacl_node_q->lock), &irqL);
++
++	DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
++
++	return ret;
++
++}
++
++#ifdef CONFIG_NATIVEAP_MLME
++
++static void update_bcn_fixed_ie(_adapter *padapter)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++}
++
++static void update_bcn_erpinfo_ie(_adapter *padapter)
++{
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
++	unsigned char *p, *ie = pnetwork->IEs;
++	u32 len = 0;
++
++	DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);
++
++	if(!pmlmeinfo->ERP_enable)
++		return;
++
++	//parsing ERP_IE
++	p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
++	if(p && len>0)
++	{
++		PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;
++
++		if (pmlmepriv->num_sta_non_erp == 1)
++			pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
++		else
++			pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
++
++		if(pmlmepriv->num_sta_no_short_preamble > 0)
++			pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
++		else
++			pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
++
++		ERP_IE_handler(padapter, pIE);
++	}
++
++}
++
++static void update_bcn_htcap_ie(_adapter *padapter)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++}
++
++static void update_bcn_htinfo_ie(_adapter *padapter)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++}
++
++static void update_bcn_rsn_ie(_adapter *padapter)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++}
++
++static void update_bcn_wpa_ie(_adapter *padapter)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++}
++
++static void update_bcn_wmm_ie(_adapter *padapter)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++}
++
++static void update_bcn_wps_ie(_adapter *padapter)
++{
++	u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL;
++	uint wps_ielen=0, wps_offset, remainder_ielen;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
++	unsigned char *ie = pnetwork->IEs;
++	u32 ielen = pnetwork->IELength;
++
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
++
++	if(pwps_ie==NULL || wps_ielen==0)
++		return;
++
++	wps_offset = (uint)(pwps_ie-ie);
++
++	premainder_ie = pwps_ie + wps_ielen;
++
++	remainder_ielen = ielen - wps_offset - wps_ielen;
++
++	if(remainder_ielen>0)
++	{
++		pbackup_remainder_ie = rtw_malloc(remainder_ielen);
++		if(pbackup_remainder_ie)
++			_rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
++	}
++
++
++	pwps_ie_src = pmlmepriv->wps_beacon_ie;
++	if(pwps_ie_src == NULL)
++		return;
++
++
++	wps_ielen = (uint)pwps_ie_src[1];//to get ie data len
++	if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
++	{
++		_rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
++		pwps_ie += (wps_ielen+2);
++
++		if(pbackup_remainder_ie)
++			_rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
++
++		//update IELength
++		pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
++	}
++
++	if(pbackup_remainder_ie)
++		rtw_mfree(pbackup_remainder_ie, remainder_ielen);
++
++}
++
++static void update_bcn_p2p_ie(_adapter *padapter)
++{
++
++}
++
++static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++
++	if(_rtw_memcmp(RTW_WPA_OUI, oui, 4))
++	{
++		update_bcn_wpa_ie(padapter);
++	}
++	else if(_rtw_memcmp(WMM_OUI, oui, 4))
++	{
++		update_bcn_wmm_ie(padapter);
++	}
++	else if(_rtw_memcmp(WPS_OUI, oui, 4))
++	{
++		update_bcn_wps_ie(padapter);
++	}
++	else if(_rtw_memcmp(P2P_OUI, oui, 4))
++	{
++		update_bcn_p2p_ie(padapter);
++	}
++	else
++	{
++		DBG_871X("unknown OUI type!\n");
++	}
++
++
++}
++
++void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
++{
++	_irqL irqL;
++	struct mlme_priv *pmlmepriv;
++	struct mlme_ext_priv	*pmlmeext;
++	//struct mlme_ext_info	*pmlmeinfo;
++
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	if(!padapter)
++		return;
++
++	pmlmepriv = &(padapter->mlmepriv);
++	pmlmeext = &(padapter->mlmeextpriv);
++	//pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	if(_FALSE == pmlmeext->bstart_bss)
++		return;
++
++	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
++
++	switch(ie_id)
++	{
++		case 0xFF:
++
++			update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability
++
++			break;
++
++		case _TIM_IE_:
++
++			update_BCNTIM(padapter);
++
++			break;
++
++		case _ERPINFO_IE_:
++
++			update_bcn_erpinfo_ie(padapter);
++
++			break;
++
++		case _HT_CAPABILITY_IE_:
++
++			update_bcn_htcap_ie(padapter);
++
++			break;
++
++		case _RSN_IE_2_:
++
++			update_bcn_rsn_ie(padapter);
++
++			break;
++
++		case _HT_ADD_INFO_IE_:
++
++			update_bcn_htinfo_ie(padapter);
++
++			break;
++
++		case _VENDOR_SPECIFIC_IE_:
++
++			update_bcn_vendor_spec_ie(padapter, oui);
++
++			break;
++
++		default:
++			break;
++	}
++
++	pmlmepriv->update_bcn = _TRUE;
++
++	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
++
++#ifndef CONFIG_INTERRUPT_BASED_TXBCN
++#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
++	if(tx)
++	{
++		//send_beacon(padapter);//send_beacon must execute on TSR level
++		set_tx_beacon_cmd(padapter);
++	}
++#else
++	{
++		//PCI will issue beacon when BCN interrupt occurs.
++	}
++#endif
++#endif //!CONFIG_INTERRUPT_BASED_TXBCN
++
++}
++
++#ifdef CONFIG_80211N_HT
++
++/*
++op_mode
++Set to 0 (HT pure) under the followign conditions
++	- all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
++	- all STAs in the BSS are 20 MHz HT in 20 MHz BSS
++Set to 1 (HT non-member protection) if there may be non-HT STAs
++	in both the primary and the secondary channel
++Set to 2 if only HT STAs are associated in BSS,
++	however and at least one 20 MHz HT STA is associated
++Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
++	(currently non-GF HT station is considered as non-HT STA also)
++*/
++static int rtw_ht_operation_update(_adapter *padapter)
++{
++	u16 cur_op_mode, new_op_mode;
++	int op_mode_changes = 0;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct ht_priv	*phtpriv_ap = &pmlmepriv->htpriv;
++
++	if(pmlmepriv->htpriv.ht_option == _TRUE)
++		return 0;
++
++	//if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
++	//	return 0;
++
++	DBG_871X("%s current operation mode=0x%X\n",
++		   __FUNCTION__, pmlmepriv->ht_op_mode);
++
++	if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
++	    && pmlmepriv->num_sta_ht_no_gf) {
++		pmlmepriv->ht_op_mode |=
++			HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
++		op_mode_changes++;
++	} else if ((pmlmepriv->ht_op_mode &
++		    HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
++		   pmlmepriv->num_sta_ht_no_gf == 0) {
++		pmlmepriv->ht_op_mode &=
++			~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
++		op_mode_changes++;
++	}
++
++	if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
++	    (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
++		pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
++		op_mode_changes++;
++	} else if ((pmlmepriv->ht_op_mode &
++		    HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
++		   (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
++		pmlmepriv->ht_op_mode &=
++			~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
++		op_mode_changes++;
++	}
++
++	/* Note: currently we switch to the MIXED op mode if HT non-greenfield
++	 * station is associated. Probably it's a theoretical case, since
++	 * it looks like all known HT STAs support greenfield.
++	 */
++	new_op_mode = 0;
++	if (pmlmepriv->num_sta_no_ht ||
++	    (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
++		new_op_mode = OP_MODE_MIXED;
++	else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)
++		 && pmlmepriv->num_sta_ht_20mhz)
++		new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
++	else if (pmlmepriv->olbc_ht)
++		new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
++	else
++		new_op_mode = OP_MODE_PURE;
++
++	cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
++	if (cur_op_mode != new_op_mode) {
++		pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
++		pmlmepriv->ht_op_mode |= new_op_mode;
++		op_mode_changes++;
++	}
++
++	DBG_871X("%s new operation mode=0x%X changes=%d\n",
++		   __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);
++
++	return op_mode_changes;
++
++}
++
++#endif /* CONFIG_80211N_HT */
++
++void associated_clients_update(_adapter *padapter, u8 updated)
++{
++	//update associcated stations cap.
++	if(updated == _TRUE)
++	{
++		_irqL irqL;
++		_list	*phead, *plist;
++		struct sta_info *psta=NULL;
++		struct sta_priv *pstapriv = &padapter->stapriv;
++
++		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++		phead = &pstapriv->asoc_list;
++		plist = get_next(phead);
++
++		//check asoc_queue
++		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++		{
++			psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
++
++			plist = get_next(plist);
++
++			VCS_update(padapter, psta);
++		}
++
++		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	}
++
++}
++
++/* called > TSR LEVEL for USB or SDIO Interface*/
++void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)
++{
++	u8 beacon_updated = _FALSE;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
++
++
++#if 0
++	if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
++	    !psta->no_short_preamble_set) {
++		psta->no_short_preamble_set = 1;
++		pmlmepriv->num_sta_no_short_preamble++;
++		if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
++		     (pmlmepriv->num_sta_no_short_preamble == 1))
++			ieee802_11_set_beacons(hapd->iface);
++	}
++#endif
++
++
++	if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE))
++	{
++		if(!psta->no_short_preamble_set)
++		{
++			psta->no_short_preamble_set = 1;
++
++			pmlmepriv->num_sta_no_short_preamble++;
++
++			if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
++				(pmlmepriv->num_sta_no_short_preamble == 1))
++			{
++				beacon_updated = _TRUE;
++				update_beacon(padapter, 0xFF, NULL, _TRUE);
++			}
++
++		}
++	}
++	else
++	{
++		if(psta->no_short_preamble_set)
++		{
++			psta->no_short_preamble_set = 0;
++
++			pmlmepriv->num_sta_no_short_preamble--;
++
++			if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
++				(pmlmepriv->num_sta_no_short_preamble == 0))
++			{
++				beacon_updated = _TRUE;
++				update_beacon(padapter, 0xFF, NULL, _TRUE);
++			}
++
++		}
++	}
++
++#if 0
++	if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {
++		psta->nonerp_set = 1;
++		pmlmepriv->num_sta_non_erp++;
++		if (pmlmepriv->num_sta_non_erp == 1)
++			ieee802_11_set_beacons(hapd->iface);
++	}
++#endif
++
++	if(psta->flags & WLAN_STA_NONERP)
++	{
++		if(!psta->nonerp_set)
++		{
++			psta->nonerp_set = 1;
++
++			pmlmepriv->num_sta_non_erp++;
++
++			if (pmlmepriv->num_sta_non_erp == 1)
++			{
++				beacon_updated = _TRUE;
++				update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
++			}
++		}
++
++	}
++	else
++	{
++		if(psta->nonerp_set)
++		{
++			psta->nonerp_set = 0;
++
++			pmlmepriv->num_sta_non_erp--;
++
++			if (pmlmepriv->num_sta_non_erp == 0)
++			{
++				beacon_updated = _TRUE;
++				update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
++			}
++		}
++
++	}
++
++
++#if 0
++	if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&
++	    !psta->no_short_slot_time_set) {
++		psta->no_short_slot_time_set = 1;
++		pmlmepriv->num_sta_no_short_slot_time++;
++		if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
++		    (pmlmepriv->num_sta_no_short_slot_time == 1))
++			ieee802_11_set_beacons(hapd->iface);
++	}
++#endif
++
++	if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT))
++	{
++		if(!psta->no_short_slot_time_set)
++		{
++			psta->no_short_slot_time_set = 1;
++
++			pmlmepriv->num_sta_no_short_slot_time++;
++
++			if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
++				 (pmlmepriv->num_sta_no_short_slot_time == 1))
++			{
++				beacon_updated = _TRUE;
++				update_beacon(padapter, 0xFF, NULL, _TRUE);
++			}
++
++		}
++	}
++	else
++	{
++		if(psta->no_short_slot_time_set)
++		{
++			psta->no_short_slot_time_set = 0;
++
++			pmlmepriv->num_sta_no_short_slot_time--;
++
++			if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
++				 (pmlmepriv->num_sta_no_short_slot_time == 0))
++			{
++				beacon_updated = _TRUE;
++				update_beacon(padapter, 0xFF, NULL, _TRUE);
++			}
++		}
++	}
++
++#ifdef CONFIG_80211N_HT
++
++	if (psta->flags & WLAN_STA_HT)
++	{
++		u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
++
++		DBG_871X("HT: STA " MAC_FMT " HT Capabilities "
++			   "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
++
++		if (psta->no_ht_set) {
++			psta->no_ht_set = 0;
++			pmlmepriv->num_sta_no_ht--;
++		}
++
++		if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
++			if (!psta->no_ht_gf_set) {
++				psta->no_ht_gf_set = 1;
++				pmlmepriv->num_sta_ht_no_gf++;
++			}
++			DBG_871X("%s STA " MAC_FMT " - no "
++				   "greenfield, num of non-gf stations %d\n",
++				   __FUNCTION__, MAC_ARG(psta->hwaddr),
++				   pmlmepriv->num_sta_ht_no_gf);
++		}
++
++		if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
++			if (!psta->ht_20mhz_set) {
++				psta->ht_20mhz_set = 1;
++				pmlmepriv->num_sta_ht_20mhz++;
++			}
++			DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "
++				   "num of 20MHz HT STAs %d\n",
++				   __FUNCTION__, MAC_ARG(psta->hwaddr),
++				   pmlmepriv->num_sta_ht_20mhz);
++		}
++
++	}
++	else
++	{
++		if (!psta->no_ht_set) {
++			psta->no_ht_set = 1;
++			pmlmepriv->num_sta_no_ht++;
++		}
++		if(pmlmepriv->htpriv.ht_option == _TRUE) {
++			DBG_871X("%s STA " MAC_FMT
++				   " - no HT, num of non-HT stations %d\n",
++				   __FUNCTION__, MAC_ARG(psta->hwaddr),
++				   pmlmepriv->num_sta_no_ht);
++		}
++	}
++
++	if (rtw_ht_operation_update(padapter) > 0)
++	{
++		update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
++		update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
++	}
++
++#endif /* CONFIG_80211N_HT */
++
++	//update associcated stations cap.
++	associated_clients_update(padapter,  beacon_updated);
++
++	DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
++
++}
++
++u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)
++{
++	u8 beacon_updated = _FALSE;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
++
++	if(!psta)
++		return beacon_updated;
++
++	if (psta->no_short_preamble_set) {
++		psta->no_short_preamble_set = 0;
++		pmlmepriv->num_sta_no_short_preamble--;
++		if (pmlmeext->cur_wireless_mode > WIRELESS_11B
++		    && pmlmepriv->num_sta_no_short_preamble == 0)
++		{
++			beacon_updated = _TRUE;
++			update_beacon(padapter, 0xFF, NULL, _TRUE);
++		}
++	}
++
++	if (psta->nonerp_set) {
++		psta->nonerp_set = 0;
++		pmlmepriv->num_sta_non_erp--;
++		if (pmlmepriv->num_sta_non_erp == 0)
++		{
++			beacon_updated = _TRUE;
++			update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
++		}
++	}
++
++	if (psta->no_short_slot_time_set) {
++		psta->no_short_slot_time_set = 0;
++		pmlmepriv->num_sta_no_short_slot_time--;
++		if (pmlmeext->cur_wireless_mode > WIRELESS_11B
++		    && pmlmepriv->num_sta_no_short_slot_time == 0)
++		{
++			beacon_updated = _TRUE;
++			update_beacon(padapter, 0xFF, NULL, _TRUE);
++		}
++	}
++
++#ifdef CONFIG_80211N_HT
++
++	if (psta->no_ht_gf_set) {
++		psta->no_ht_gf_set = 0;
++		pmlmepriv->num_sta_ht_no_gf--;
++	}
++
++	if (psta->no_ht_set) {
++		psta->no_ht_set = 0;
++		pmlmepriv->num_sta_no_ht--;
++	}
++
++	if (psta->ht_20mhz_set) {
++		psta->ht_20mhz_set = 0;
++		pmlmepriv->num_sta_ht_20mhz--;
++	}
++
++	if (rtw_ht_operation_update(padapter) > 0)
++	{
++		update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
++		update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
++	}
++
++#endif /* CONFIG_80211N_HT */
++
++	//update associcated stations cap.
++	//associated_clients_update(padapter,  beacon_updated); //move it to avoid deadlock
++
++	DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
++
++	return beacon_updated;
++
++}
++
++u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
++{
++	_irqL irqL;
++	u8 beacon_updated = _FALSE;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct sta_priv *pstapriv = &padapter->stapriv;
++
++	if(!psta)
++		return beacon_updated;
++
++	if (active == _TRUE)
++	{
++#ifdef CONFIG_80211N_HT
++		//tear down Rx AMPDU
++		send_delba(padapter, 0, psta->hwaddr);// recipient
++
++		//tear down TX AMPDU
++		send_delba(padapter, 1, psta->hwaddr);// // originator
++
++#endif //CONFIG_80211N_HT
++
++		issue_deauth(padapter, psta->hwaddr, reason);
++	}
++
++	psta->htpriv.agg_enable_bitmap = 0x0;//reset
++	psta->htpriv.candidate_tid_bitmap = 0x0;//reset
++
++
++	//report_del_sta_event(padapter, psta->hwaddr, reason);
++
++	//clear cam entry / key
++	//clear_cam_entry(padapter, (psta->mac_id + 3));
++	rtw_clearstakey_cmd(padapter, (u8*)psta, (u8)(psta->mac_id + 3), _TRUE);
++
++
++	_enter_critical_bh(&psta->lock, &irqL);
++	psta->state &= ~_FW_LINKED;
++	_exit_critical_bh(&psta->lock, &irqL);
++
++	#ifdef CONFIG_IOCTL_CFG80211
++	if (1) {
++		#ifdef COMPAT_KERNEL_RELEASE
++		rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
++		#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++		rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
++		#else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++		/* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */
++		#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++	} else
++	#endif //CONFIG_IOCTL_CFG80211
++	{
++		rtw_indicate_sta_disassoc_event(padapter, psta);
++	}
++
++	report_del_sta_event(padapter, psta->hwaddr, reason);
++
++	beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
++
++	_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++	rtw_free_stainfo(padapter, psta);
++	_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++
++	return beacon_updated;
++
++}
++
++int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)
++{
++	_irqL irqL;
++	_list	*phead, *plist;
++	int ret=0;
++	struct sta_info *psta = NULL;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
++
++	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
++		return ret;
++
++	DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
++		FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
++
++	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++	phead = &pstapriv->asoc_list;
++	plist = get_next(phead);
++
++	/* for each sta in asoc_queue */
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++	{
++		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
++		plist = get_next(plist);
++
++		issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
++		psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
++	}
++	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
++
++	return ret;
++}
++
++int rtw_sta_flush(_adapter *padapter)
++{
++	_irqL irqL;
++	_list	*phead, *plist;
++	int ret=0;
++	struct sta_info *psta = NULL;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
++	u8 chk_alive_num = 0;
++	char chk_alive_list[NUM_STA];
++	int i;
++
++	DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
++
++	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
++		return ret;
++
++	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++	phead = &pstapriv->asoc_list;
++	plist = get_next(phead);
++
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
++		int stainfo_offset;
++
++		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
++		plist = get_next(plist);
++
++		/* Remove sta from asoc_list */
++		rtw_list_delete(&psta->asoc_list);
++		pstapriv->asoc_list_cnt--;
++
++		/* Keep sta for ap_free_sta() beyond this asoc_list loop */
++		stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
++		if (stainfo_offset_valid(stainfo_offset)) {
++			chk_alive_list[chk_alive_num++] = stainfo_offset;
++		}
++	}
++	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++
++	/* For each sta in chk_alive_list, call ap_free_sta */
++	for (i = 0; i < chk_alive_num; i++) {
++		psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
++		ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
++	}
++
++	issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
++
++	associated_clients_update(padapter, _TRUE);
++
++	return ret;
++
++}
++
++/* called > TSR LEVEL for USB or SDIO Interface*/
++void sta_info_update(_adapter *padapter, struct sta_info *psta)
++{
++	int flags = psta->flags;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++
++	//update wmm cap.
++	if(WLAN_STA_WME&flags)
++		psta->qos_option = 1;
++	else
++		psta->qos_option = 0;
++
++	if(pmlmepriv->qospriv.qos_option == 0)
++		psta->qos_option = 0;
++
++
++#ifdef CONFIG_80211N_HT
++	//update 802.11n ht cap.
++	if(WLAN_STA_HT&flags)
++	{
++		psta->htpriv.ht_option = _TRUE;
++		psta->qos_option = 1;
++	}
++	else
++	{
++		psta->htpriv.ht_option = _FALSE;
++	}
++
++	if(pmlmepriv->htpriv.ht_option == _FALSE)
++		psta->htpriv.ht_option = _FALSE;
++#endif
++
++
++	update_sta_info_apmode(padapter, psta);
++
++
++}
++
++/* called >= TSR LEVEL for USB or SDIO Interface*/
++void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)
++{
++	if(psta->state & _FW_LINKED)
++	{
++		//add ratid
++		add_RATid(padapter, psta);
++	}
++}
++
++/* restore hw setting from sw data structures */
++void rtw_ap_restore_network(_adapter *padapter)
++{
++	struct mlme_priv *mlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct sta_priv * pstapriv = &padapter->stapriv;
++	struct sta_info *psta;
++	struct security_priv* psecuritypriv=&(padapter->securitypriv);
++	_irqL irqL;
++	_list	*phead, *plist;
++	u8 chk_alive_num = 0;
++	char chk_alive_list[NUM_STA];
++	int i;
++
++	rtw_setopmode_cmd(padapter, Ndis802_11APMode);
++
++	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
++
++	start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);
++
++	if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
++		(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
++	{
++		/* restore group key, WEP keys is restored in ips_leave() */
++		rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0);
++	}
++
++	/* per sta pairwise key and settings */
++	if((padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_) &&
++		(padapter->securitypriv.dot11PrivacyAlgrthm != _AES_)) {
++		return;
++	}
++
++	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	phead = &pstapriv->asoc_list;
++	plist = get_next(phead);
++
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
++		int stainfo_offset;
++
++		psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
++		plist = get_next(plist);
++
++		stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
++		if (stainfo_offset_valid(stainfo_offset)) {
++			chk_alive_list[chk_alive_num++] = stainfo_offset;
++		}
++	}
++
++	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	for (i = 0; i < chk_alive_num; i++) {
++		psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
++
++		if (psta == NULL) {
++			DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
++		} else if (psta->state &_FW_LINKED) {
++			Update_RA_Entry(padapter, psta->mac_id);
++			//pairwise key
++			rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
++		}
++	}
++
++}
++
++void start_ap_mode(_adapter *padapter)
++{
++	int i;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
++
++	pmlmepriv->update_bcn = _FALSE;
++
++	//init_mlme_ap_info(padapter);
++	pmlmeext->bstart_bss = _FALSE;
++
++	pmlmepriv->num_sta_non_erp = 0;
++
++	pmlmepriv->num_sta_no_short_slot_time = 0;
++
++	pmlmepriv->num_sta_no_short_preamble = 0;
++
++	pmlmepriv->num_sta_ht_no_gf = 0;
++
++	pmlmepriv->num_sta_no_ht = 0;
++
++	pmlmepriv->num_sta_ht_20mhz = 0;
++
++	pmlmepriv->olbc = _FALSE;
++
++	pmlmepriv->olbc_ht = _FALSE;
++
++#ifdef CONFIG_80211N_HT
++	pmlmepriv->ht_op_mode = 0;
++#endif
++
++	for(i=0; i<NUM_STA; i++)
++		pstapriv->sta_aid[i] = NULL;
++
++	pmlmepriv->wps_beacon_ie = NULL;
++	pmlmepriv->wps_probe_resp_ie = NULL;
++	pmlmepriv->wps_assoc_resp_ie = NULL;
++
++	pmlmepriv->p2p_beacon_ie = NULL;
++	pmlmepriv->p2p_probe_resp_ie = NULL;
++
++
++	//for ACL
++	_rtw_init_listhead(&(pacl_list->acl_node_q.queue));
++	pacl_list->num = 0;
++	pacl_list->mode = 0;
++	for(i = 0; i < NUM_ACL; i++)
++	{
++		_rtw_init_listhead(&pacl_list->aclnode[i].list);
++		pacl_list->aclnode[i].valid = _FALSE;
++	}
++
++}
++
++void stop_ap_mode(_adapter *padapter)
++{
++	_irqL irqL;
++	_list	*phead, *plist;
++	struct rtw_wlan_acl_node *paclnode;
++	struct sta_info *psta=NULL;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
++	_queue	*pacl_node_q =&pacl_list->acl_node_q;
++
++	pmlmepriv->update_bcn = _FALSE;
++	pmlmeext->bstart_bss = _FALSE;
++	//_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
++
++	//reset and init security priv , this can refine with rtw_reset_securitypriv
++	_rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));
++	padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
++	padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
++
++	//for ACL
++	_enter_critical_bh(&(pacl_node_q->lock), &irqL);
++	phead = get_list_head(pacl_node_q);
++	plist = get_next(phead);
++	while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++	{
++		paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
++		plist = get_next(plist);
++
++		if(paclnode->valid == _TRUE)
++		{
++			paclnode->valid = _FALSE;
++
++			rtw_list_delete(&paclnode->list);
++
++			pacl_list->num--;
++		}
++	}
++	_exit_critical_bh(&(pacl_node_q->lock), &irqL);
++
++	DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);
++
++	rtw_sta_flush(padapter);
++
++	//free_assoc_sta_resources
++	rtw_free_all_stainfo(padapter);
++
++	psta = rtw_get_bcmc_stainfo(padapter);
++	_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++	rtw_free_stainfo(padapter, psta);
++	_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++	rtw_init_bcmc_stainfo(padapter);
++
++	rtw_free_mlme_priv_ie_data(pmlmepriv);
++
++}
++
++#endif //CONFIG_NATIVEAP_MLME
++#endif //CONFIG_AP_MODE
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_br_ext.c
+@@ -0,0 +1,1699 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_BR_EXT_C_
++
++#ifdef __KERNEL__
++#include <linux/if_arp.h>
++#include <net/ip.h>
++#include <net/ipx.h>
++#include <linux/atalk.h>
++#include <linux/udp.h>
++#include <linux/if_pppox.h>
++#endif
++
++#if 1	// rtw_wifi_driver
++#include <drv_conf.h>
++#include <drv_types.h>
++#include "rtw_br_ext.h"
++#else	// rtw_wifi_driver
++#include "./8192cd_cfg.h"
++
++#ifndef __KERNEL__
++#include "./sys-support.h"
++#endif
++
++#include "./8192cd.h"
++#include "./8192cd_headers.h"
++#include "./8192cd_br_ext.h"
++#include "./8192cd_debug.h"
++#endif	// rtw_wifi_driver
++
++#ifdef CL_IPV6_PASS
++#ifdef __KERNEL__
++#include <linux/ipv6.h>
++#include <linux/icmpv6.h>
++#include <net/ndisc.h>
++#include <net/checksum.h>
++#endif
++#endif
++
++#ifdef CONFIG_BR_EXT
++
++//#define BR_EXT_DEBUG
++
++#define NAT25_IPV4		01
++#define NAT25_IPV6		02
++#define NAT25_IPX		03
++#define NAT25_APPLE		04
++#define NAT25_PPPOE		05
++
++#define RTL_RELAY_TAG_LEN (ETH_ALEN)
++#define TAG_HDR_LEN		4
++
++#define MAGIC_CODE		0x8186
++#define MAGIC_CODE_LEN	2
++#define WAIT_TIME_PPPOE	5	// waiting time for pppoe server in sec
++
++/*-----------------------------------------------------------------
++  How database records network address:
++           0    1    2    3    4    5    6    7    8    9   10
++        |----|----|----|----|----|----|----|----|----|----|----|
++  IPv4  |type|                             |      IP addr      |
++  IPX   |type|      Net addr     |          Node addr          |
++  IPX   |type|      Net addr     |Sckt addr|
++  Apple |type| Network |node|
++  PPPoE |type|   SID   |           AC MAC            |
++-----------------------------------------------------------------*/
++
++
++//Find a tag in pppoe frame and return the pointer
++static __inline__ unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type)
++{
++	unsigned char *cur_ptr, *start_ptr;
++	unsigned short tagLen, tagType;
++
++	start_ptr = cur_ptr = (unsigned char *)ph->tag;
++	while((cur_ptr - start_ptr) < ntohs(ph->length)) {
++		// prevent un-alignment access
++		tagType = (unsigned short)((cur_ptr[0] << 8) + cur_ptr[1]);
++		tagLen  = (unsigned short)((cur_ptr[2] << 8) + cur_ptr[3]);
++		if(tagType == type)
++			return cur_ptr;
++		cur_ptr = cur_ptr + TAG_HDR_LEN + tagLen;
++	}
++	return 0;
++}
++
++
++static __inline__ int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag)
++{
++	struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
++	int data_len;
++
++	data_len = tag->tag_len + TAG_HDR_LEN;
++	if (skb_tailroom(skb) < data_len) {
++		_DEBUG_ERR("skb_tailroom() failed in add SID tag!\n");
++		return -1;
++	}
++
++	skb_put(skb, data_len);
++	// have a room for new tag
++	memmove(((unsigned char *)ph->tag + data_len), (unsigned char *)ph->tag, ntohs(ph->length));
++	ph->length = htons(ntohs(ph->length) + data_len);
++	memcpy((unsigned char *)ph->tag, tag, data_len);
++	return data_len;
++}
++
++static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len)
++{
++	int tail_len;
++	unsigned long end, tail;
++
++	if ((src+len) > skb_tail_pointer(skb) || skb->len < len)
++		return -1;
++
++	tail = (unsigned long)skb_tail_pointer(skb);
++	end = (unsigned long)src+len;
++	if (tail < end)
++		return -1;
++
++	tail_len = (int)(tail-end);
++	if (tail_len > 0)
++		memmove(src, src+len, tail_len);
++
++	skb_trim(skb, skb->len-len);
++	return 0;
++}
++
++static __inline__ unsigned long __nat25_timeout(_adapter *priv)
++{
++	unsigned long timeout;
++
++	timeout = jiffies - NAT25_AGEING_TIME*HZ;
++
++	return timeout;
++}
++
++
++static __inline__ int  __nat25_has_expired(_adapter *priv,
++				struct nat25_network_db_entry *fdb)
++{
++	if(time_before_eq(fdb->ageing_timer, __nat25_timeout(priv)))
++		return 1;
++
++	return 0;
++}
++
++
++static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr,
++				unsigned int *ipAddr)
++{
++	memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
++
++	networkAddr[0] = NAT25_IPV4;
++	memcpy(networkAddr+7, (unsigned char *)ipAddr, 4);
++}
++
++
++static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr,
++				unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr)
++{
++	memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
++
++	networkAddr[0] = NAT25_IPX;
++	memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4);
++	memcpy(networkAddr+5, ipxNodeAddr, 6);
++}
++
++
++static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr,
++				unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr)
++{
++	memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
++
++	networkAddr[0] = NAT25_IPX;
++	memcpy(networkAddr+1, (unsigned char *)ipxNetAddr, 4);
++	memcpy(networkAddr+5, (unsigned char *)ipxSocketAddr, 2);
++}
++
++
++static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networkAddr,
++				unsigned short *network, unsigned char *node)
++{
++	memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
++
++	networkAddr[0] = NAT25_APPLE;
++	memcpy(networkAddr+1, (unsigned char *)network, 2);
++	networkAddr[3] = *node;
++}
++
++
++static __inline__ void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr,
++				unsigned char *ac_mac, unsigned short *sid)
++{
++	memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
++
++	networkAddr[0] = NAT25_PPPOE;
++	memcpy(networkAddr+1, (unsigned char *)sid, 2);
++	memcpy(networkAddr+3, (unsigned char *)ac_mac, 6);
++}
++
++
++#ifdef CL_IPV6_PASS
++static  void __nat25_generate_ipv6_network_addr(unsigned char *networkAddr,
++				unsigned int *ipAddr)
++{
++	memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN);
++
++	networkAddr[0] = NAT25_IPV6;
++	memcpy(networkAddr+1, (unsigned char *)ipAddr, 16);
++}
++
++
++static unsigned char *scan_tlv(unsigned char *data, int len, unsigned char tag, unsigned char len8b)
++{
++	while (len > 0) {
++		if (*data == tag && *(data+1) == len8b && len >= len8b*8)
++			return data+2;
++
++		len -= (*(data+1))*8;
++		data += (*(data+1))*8;
++	}
++	return NULL;
++}
++
++
++static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char *replace_mac)
++{
++	struct icmp6hdr *icmphdr = (struct icmp6hdr *)data;
++	unsigned char *mac;
++
++	if (icmphdr->icmp6_type == NDISC_ROUTER_SOLICITATION) {
++		if (len >= 8) {
++			mac = scan_tlv(&data[8], len-8, 1, 1);
++			if (mac) {
++				_DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
++					mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
++					replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]);
++				memcpy(mac, replace_mac, 6);
++				return 1;
++			}
++		}
++	}
++	else if (icmphdr->icmp6_type == NDISC_ROUTER_ADVERTISEMENT) {
++		if (len >= 16) {
++			mac = scan_tlv(&data[16], len-16, 1, 1);
++			if (mac) {
++				_DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
++					mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
++					replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]);
++				memcpy(mac, replace_mac, 6);
++				return 1;
++			}
++		}
++	}
++	else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
++		if (len >= 24) {
++			mac = scan_tlv(&data[24], len-24, 1, 1);
++			if (mac) {
++				_DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
++					mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
++					replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]);
++				memcpy(mac, replace_mac, 6);
++				return 1;
++			}
++		}
++	}
++	else if (icmphdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) {
++		if (len >= 24) {
++			mac = scan_tlv(&data[24], len-24, 2, 1);
++			if (mac) {
++				_DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
++					mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
++					replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]);
++				memcpy(mac, replace_mac, 6);
++				return 1;
++			}
++		}
++	}
++	else if (icmphdr->icmp6_type == NDISC_REDIRECT) {
++		if (len >= 40) {
++			mac = scan_tlv(&data[40], len-40, 2, 1);
++			if (mac) {
++				_DEBUG_INFO("Redirect,  replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n",
++					mac[0],mac[1],mac[2],mac[3],mac[4],mac[5],
++					replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]);
++				memcpy(mac, replace_mac, 6);
++				return 1;
++			}
++		}
++	}
++	return 0;
++}
++
++
++static void convert_ipv6_mac_to_mc(struct sk_buff *skb)
++{
++	struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
++	unsigned char *dst_mac = skb->data;
++
++	//dst_mac[0] = 0xff;
++	//dst_mac[1] = 0xff;
++	/*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/
++	dst_mac[0] = 0x33;
++	dst_mac[1] = 0x33;
++	memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4);
++	#if defined(__LINUX_2_6__)
++	/*modified by qinjunjie,warning:should not remove next line*/
++	skb->pkt_type = PACKET_MULTICAST;
++	#endif
++}
++#endif /* CL_IPV6_PASS */
++
++
++static __inline__ int __nat25_network_hash(unsigned char *networkAddr)
++{
++	if(networkAddr[0] == NAT25_IPV4)
++	{
++		unsigned long x;
++
++		x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10];
++
++		return x & (NAT25_HASH_SIZE - 1);
++	}
++	else if(networkAddr[0] == NAT25_IPX)
++	{
++		unsigned long x;
++
++		x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^
++			networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10];
++
++		return x & (NAT25_HASH_SIZE - 1);
++	}
++	else if(networkAddr[0] == NAT25_APPLE)
++	{
++		unsigned long x;
++
++		x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3];
++
++		return x & (NAT25_HASH_SIZE - 1);
++	}
++	else if(networkAddr[0] == NAT25_PPPOE)
++	{
++		unsigned long x;
++
++		x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8];
++
++		return x & (NAT25_HASH_SIZE - 1);
++	}
++#ifdef CL_IPV6_PASS
++	else if(networkAddr[0] == NAT25_IPV6)
++	{
++		unsigned long x;
++
++		x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^
++			networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10] ^
++			networkAddr[11] ^ networkAddr[12] ^ networkAddr[13] ^ networkAddr[14] ^ networkAddr[15] ^
++			networkAddr[16];
++
++		return x & (NAT25_HASH_SIZE - 1);
++	}
++#endif
++	else
++	{
++		unsigned long x = 0;
++		int i;
++
++		for (i=0; i<MAX_NETWORK_ADDR_LEN; i++)
++			x ^= networkAddr[i];
++
++		return x & (NAT25_HASH_SIZE - 1);
++	}
++}
++
++
++static __inline__ void __network_hash_link(_adapter *priv,
++				struct nat25_network_db_entry *ent, int hash)
++{
++	// Caller must _enter_critical_bh already!
++	//_irqL irqL;
++	//_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	ent->next_hash = priv->nethash[hash];
++	if(ent->next_hash != NULL)
++		ent->next_hash->pprev_hash = &ent->next_hash;
++	priv->nethash[hash] = ent;
++	ent->pprev_hash = &priv->nethash[hash];
++
++	//_exit_critical_bh(&priv->br_ext_lock, &irqL);
++}
++
++
++static __inline__ void __network_hash_unlink(struct nat25_network_db_entry *ent)
++{
++	// Caller must _enter_critical_bh already!
++	//_irqL irqL;
++	//_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	*(ent->pprev_hash) = ent->next_hash;
++	if(ent->next_hash != NULL)
++		ent->next_hash->pprev_hash = ent->pprev_hash;
++	ent->next_hash = NULL;
++	ent->pprev_hash = NULL;
++
++	//_exit_critical_bh(&priv->br_ext_lock, &irqL);
++}
++
++
++static int __nat25_db_network_lookup_and_replace(_adapter *priv,
++				struct sk_buff *skb, unsigned char *networkAddr)
++{
++	struct nat25_network_db_entry *db;
++	_irqL irqL;
++	_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	db = priv->nethash[__nat25_network_hash(networkAddr)];
++	while (db != NULL)
++	{
++		if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN))
++		{
++			if(!__nat25_has_expired(priv, db))
++			{
++				// replace the destination mac address
++				memcpy(skb->data, db->macAddr, ETH_ALEN);
++				atomic_inc(&db->use_count);
++
++#ifdef CL_IPV6_PASS
++				DEBUG_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
++							"%02x%02x%02x%02x%02x%02x\n",
++					db->macAddr[0],
++					db->macAddr[1],
++					db->macAddr[2],
++					db->macAddr[3],
++					db->macAddr[4],
++					db->macAddr[5],
++					db->networkAddr[0],
++					db->networkAddr[1],
++					db->networkAddr[2],
++					db->networkAddr[3],
++					db->networkAddr[4],
++					db->networkAddr[5],
++					db->networkAddr[6],
++					db->networkAddr[7],
++					db->networkAddr[8],
++					db->networkAddr[9],
++					db->networkAddr[10],
++					db->networkAddr[11],
++					db->networkAddr[12],
++					db->networkAddr[13],
++					db->networkAddr[14],
++					db->networkAddr[15],
++					db->networkAddr[16]);
++#else
++				DEBUG_INFO("NAT25: Lookup M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
++					db->macAddr[0],
++					db->macAddr[1],
++					db->macAddr[2],
++					db->macAddr[3],
++					db->macAddr[4],
++					db->macAddr[5],
++					db->networkAddr[0],
++					db->networkAddr[1],
++					db->networkAddr[2],
++					db->networkAddr[3],
++					db->networkAddr[4],
++					db->networkAddr[5],
++					db->networkAddr[6],
++					db->networkAddr[7],
++					db->networkAddr[8],
++					db->networkAddr[9],
++					db->networkAddr[10]);
++#endif
++			}
++			_exit_critical_bh(&priv->br_ext_lock, &irqL);
++			return 1;
++		}
++
++		db = db->next_hash;
++	}
++
++	_exit_critical_bh(&priv->br_ext_lock, &irqL);
++	return 0;
++}
++
++
++static void __nat25_db_network_insert(_adapter *priv,
++				unsigned char *macAddr, unsigned char *networkAddr)
++{
++	struct nat25_network_db_entry *db;
++	int hash;
++	_irqL irqL;
++	_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	hash = __nat25_network_hash(networkAddr);
++	db = priv->nethash[hash];
++	while (db != NULL)
++	{
++		if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN))
++		{
++			memcpy(db->macAddr, macAddr, ETH_ALEN);
++			db->ageing_timer = jiffies;
++			_exit_critical_bh(&priv->br_ext_lock, &irqL);
++			return;
++		}
++
++		db = db->next_hash;
++	}
++
++	db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db));
++	if(db == NULL) {
++		_exit_critical_bh(&priv->br_ext_lock, &irqL);
++		return;
++	}
++
++	memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN);
++	memcpy(db->macAddr, macAddr, ETH_ALEN);
++	atomic_set(&db->use_count, 1);
++	db->ageing_timer = jiffies;
++
++	__network_hash_link(priv, db, hash);
++
++	_exit_critical_bh(&priv->br_ext_lock, &irqL);
++}
++
++
++static void __nat25_db_print(_adapter *priv)
++{
++	_irqL irqL;
++	_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++#ifdef BR_EXT_DEBUG
++	static int counter = 0;
++	int i, j;
++	struct nat25_network_db_entry *db;
++
++	counter++;
++	if((counter % 16) != 0)
++		return;
++
++	for(i=0, j=0; i<NAT25_HASH_SIZE; i++)
++	{
++		db = priv->nethash[i];
++
++		while (db != NULL)
++		{
++#ifdef CL_IPV6_PASS
++			panic_printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
++					"%02x%02x%02x%02x%02x%02x\n",
++				j,
++				i,
++				atomic_read(&db->use_count),
++				db->macAddr[0],
++				db->macAddr[1],
++				db->macAddr[2],
++				db->macAddr[3],
++				db->macAddr[4],
++				db->macAddr[5],
++				db->networkAddr[0],
++				db->networkAddr[1],
++				db->networkAddr[2],
++				db->networkAddr[3],
++				db->networkAddr[4],
++				db->networkAddr[5],
++				db->networkAddr[6],
++				db->networkAddr[7],
++				db->networkAddr[8],
++				db->networkAddr[9],
++				db->networkAddr[10],
++				db->networkAddr[11],
++				db->networkAddr[12],
++				db->networkAddr[13],
++				db->networkAddr[14],
++				db->networkAddr[15],
++				db->networkAddr[16]);
++#else
++			panic_printk("NAT25: DB(%d) H(%02d) C(%d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
++				j,
++				i,
++				atomic_read(&db->use_count),
++				db->macAddr[0],
++				db->macAddr[1],
++				db->macAddr[2],
++				db->macAddr[3],
++				db->macAddr[4],
++				db->macAddr[5],
++				db->networkAddr[0],
++				db->networkAddr[1],
++				db->networkAddr[2],
++				db->networkAddr[3],
++				db->networkAddr[4],
++				db->networkAddr[5],
++				db->networkAddr[6],
++				db->networkAddr[7],
++				db->networkAddr[8],
++				db->networkAddr[9],
++				db->networkAddr[10]);
++#endif
++			j++;
++
++			db = db->next_hash;
++		}
++	}
++#endif
++
++	_exit_critical_bh(&priv->br_ext_lock, &irqL);
++}
++
++
++
++
++/*
++ *	NAT2.5 interface
++ */
++
++void nat25_db_cleanup(_adapter *priv)
++{
++	int i;
++	_irqL irqL;
++	_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	for(i=0; i<NAT25_HASH_SIZE; i++)
++	{
++		struct nat25_network_db_entry *f;
++		f = priv->nethash[i];
++		while (f != NULL) {
++			struct nat25_network_db_entry *g;
++
++			g = f->next_hash;
++			if(priv->scdb_entry == f)
++			{
++				memset(priv->scdb_mac, 0, ETH_ALEN);
++				memset(priv->scdb_ip, 0, 4);
++				priv->scdb_entry = NULL;
++			}
++			__network_hash_unlink(f);
++			rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry));
++
++			f = g;
++		}
++	}
++
++	_exit_critical_bh(&priv->br_ext_lock, &irqL);
++}
++
++
++void nat25_db_expire(_adapter *priv)
++{
++	int i;
++	_irqL irqL;
++	_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	//if(!priv->ethBrExtInfo.nat25_disable)
++	{
++		for (i=0; i<NAT25_HASH_SIZE; i++)
++		{
++			struct nat25_network_db_entry *f;
++			f = priv->nethash[i];
++
++			while (f != NULL)
++			{
++				struct nat25_network_db_entry *g;
++				g = f->next_hash;
++
++				if(__nat25_has_expired(priv, f))
++				{
++					if(atomic_dec_and_test(&f->use_count))
++					{
++#ifdef BR_EXT_DEBUG
++#ifdef CL_IPV6_PASS
++						panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
++								"%02x%02x%02x%02x%02x%02x\n",
++							i,
++							f->macAddr[0],
++							f->macAddr[1],
++							f->macAddr[2],
++							f->macAddr[3],
++							f->macAddr[4],
++							f->macAddr[5],
++							f->networkAddr[0],
++							f->networkAddr[1],
++							f->networkAddr[2],
++							f->networkAddr[3],
++							f->networkAddr[4],
++							f->networkAddr[5],
++							f->networkAddr[6],
++							f->networkAddr[7],
++							f->networkAddr[8],
++							f->networkAddr[9],
++							f->networkAddr[10],
++							f->networkAddr[11],
++							f->networkAddr[12],
++							f->networkAddr[13],
++							f->networkAddr[14],
++							f->networkAddr[15],
++							f->networkAddr[16]);
++#else
++
++						panic_printk("NAT25 Expire H(%02d) M:%02x%02x%02x%02x%02x%02x N:%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
++							i,
++							f->macAddr[0],
++							f->macAddr[1],
++							f->macAddr[2],
++							f->macAddr[3],
++							f->macAddr[4],
++							f->macAddr[5],
++							f->networkAddr[0],
++							f->networkAddr[1],
++							f->networkAddr[2],
++							f->networkAddr[3],
++							f->networkAddr[4],
++							f->networkAddr[5],
++							f->networkAddr[6],
++							f->networkAddr[7],
++							f->networkAddr[8],
++							f->networkAddr[9],
++							f->networkAddr[10]);
++#endif
++#endif
++						if(priv->scdb_entry == f)
++						{
++							memset(priv->scdb_mac, 0, ETH_ALEN);
++							memset(priv->scdb_ip, 0, 4);
++							priv->scdb_entry = NULL;
++						}
++						__network_hash_unlink(f);
++						rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry));
++					}
++				}
++
++				f = g;
++			}
++		}
++	}
++
++	_exit_critical_bh(&priv->br_ext_lock, &irqL);
++}
++
++
++#ifdef SUPPORT_TX_MCAST2UNI
++static int checkIPMcAndReplace(_adapter *priv, struct sk_buff *skb, unsigned int *dst_ip)
++{
++	struct stat_info	*pstat;
++	struct list_head	*phead, *plist;
++	int i;
++
++	phead = &priv->asoc_list;
++	plist = phead->next;
++
++	while (plist != phead) {
++		pstat = list_entry(plist, struct stat_info, asoc_list);
++		plist = plist->next;
++
++		if (pstat->ipmc_num == 0)
++			continue;
++
++		for (i=0; i<MAX_IP_MC_ENTRY; i++) {
++			if (pstat->ipmc[i].used && !memcmp(&pstat->ipmc[i].mcmac[3], ((unsigned char *)dst_ip)+1, 3)) {
++				memcpy(skb->data, pstat->ipmc[i].mcmac, ETH_ALEN);
++				return 1;
++			}
++		}
++	}
++	return 0;
++}
++#endif
++
++int nat25_db_handle(_adapter *priv, struct sk_buff *skb, int method)
++{
++	unsigned short protocol;
++	unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
++
++	if(skb == NULL)
++		return -1;
++
++	if((method <= NAT25_MIN) || (method >= NAT25_MAX))
++		return -1;
++
++	protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
++
++	/*---------------------------------------------------*/
++	/*                 Handle IP frame                   */
++	/*---------------------------------------------------*/
++	if(protocol == __constant_htons(ETH_P_IP))
++	{
++		struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN);
++
++		if(((unsigned char*)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len))
++		{
++			DEBUG_WARN("NAT25: malformed IP packet !\n");
++			return -1;
++		}
++
++		switch(method)
++		{
++			case NAT25_CHECK:
++				return -1;
++
++			case NAT25_INSERT:
++				{
++					//some muticast with source IP is all zero, maybe other case is illegal
++					//in class A, B, C, host address is all zero or all one is illegal
++					if (iph->saddr == 0)
++						return 0;
++					DEBUG_INFO("NAT25: Insert IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr);
++					__nat25_generate_ipv4_network_addr(networkAddr, &iph->saddr);
++					//record source IP address and , source mac address into db
++					__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++
++					__nat25_db_print(priv);
++				}
++				return 0;
++
++			case NAT25_LOOKUP:
++				{
++					DEBUG_INFO("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr);
++#ifdef SUPPORT_TX_MCAST2UNI
++					if (priv->pshare->rf_ft_var.mc2u_disable ||
++							((((OPMODE & (WIFI_STATION_STATE|WIFI_ASOC_STATE))
++							== (WIFI_STATION_STATE|WIFI_ASOC_STATE)) &&
++							!checkIPMcAndReplace(priv, skb, &iph->daddr)) ||
++							(OPMODE & WIFI_ADHOC_STATE)))
++#endif
++					{
++						__nat25_generate_ipv4_network_addr(networkAddr, &iph->daddr);
++
++						if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) {
++							if (*((unsigned char *)&iph->daddr + 3) == 0xff) {
++								// L2 is unicast but L3 is broadcast, make L2 bacome broadcast
++								DEBUG_INFO("NAT25: Set DA as boardcast\n");
++								memset(skb->data, 0xff, ETH_ALEN);
++							}
++							else {
++								// forward unknow IP packet to upper TCP/IP
++								DEBUG_INFO("NAT25: Replace DA with BR's MAC\n");
++								if ( (*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0 ) {
++									void netdev_br_init(struct net_device *netdev);
++									printk("Re-init netdev_br_init() due to br_mac==0!\n");
++									netdev_br_init(priv->pnetdev);
++								}
++								memcpy(skb->data, priv->br_mac, ETH_ALEN);
++							}
++						}
++					}
++				}
++				return 0;
++
++			default:
++				return -1;
++		}
++	}
++
++	/*---------------------------------------------------*/
++	/*                 Handle ARP frame                  */
++	/*---------------------------------------------------*/
++	else if(protocol == __constant_htons(ETH_P_ARP))
++	{
++		struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN);
++		unsigned char *arp_ptr = (unsigned char *)(arp + 1);
++		unsigned int *sender, *target;
++
++		if(arp->ar_pro != __constant_htons(ETH_P_IP))
++		{
++			DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", htons(arp->ar_pro));
++			return -1;
++		}
++
++		switch(method)
++		{
++			case NAT25_CHECK:
++				return 0;	// skb_copy for all ARP frame
++
++			case NAT25_INSERT:
++				{
++					DEBUG_INFO("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0],
++						arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]);
++
++					// change to ARP sender mac address to wlan STA address
++                                        memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN);
++
++					arp_ptr += arp->ar_hln;
++					sender = (unsigned int *)arp_ptr;
++
++					__nat25_generate_ipv4_network_addr(networkAddr, sender);
++
++					__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++
++					__nat25_db_print(priv);
++				}
++				return 0;
++
++			case NAT25_LOOKUP:
++				{
++					DEBUG_INFO("NAT25: Lookup ARP\n");
++
++					arp_ptr += arp->ar_hln;
++					sender = (unsigned int *)arp_ptr;
++					arp_ptr += (arp->ar_hln + arp->ar_pln);
++					target = (unsigned int *)arp_ptr;
++
++					__nat25_generate_ipv4_network_addr(networkAddr, target);
++
++					__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
++
++					// change to ARP target mac address to Lookup result
++					arp_ptr = (unsigned char *)(arp + 1);
++					arp_ptr += (arp->ar_hln + arp->ar_pln);
++					memcpy(arp_ptr, skb->data, ETH_ALEN);
++				}
++				return 0;
++
++			default:
++				return -1;
++		}
++	}
++
++	/*---------------------------------------------------*/
++	/*         Handle IPX and Apple Talk frame           */
++	/*---------------------------------------------------*/
++	else if((protocol == __constant_htons(ETH_P_IPX)) ||
++		(protocol <= __constant_htons(ETH_FRAME_LEN)))
++	{
++		unsigned char ipx_header[2] = {0xFF, 0xFF};
++		struct ipxhdr	*ipx = NULL;
++		struct elapaarp	*ea = NULL;
++		struct ddpehdr	*ddp = NULL;
++		unsigned char *framePtr = skb->data + ETH_HLEN;
++
++		if(protocol == __constant_htons(ETH_P_IPX))
++		{
++			DEBUG_INFO("NAT25: Protocol=IPX (Ethernet II)\n");
++			ipx = (struct ipxhdr *)framePtr;
++		}
++		else if(protocol <= __constant_htons(ETH_FRAME_LEN))
++		{
++			if(!memcmp(ipx_header, framePtr, 2))
++			{
++				DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.3)\n");
++				ipx = (struct ipxhdr *)framePtr;
++			}
++			else
++			{
++				unsigned char ipx_8022_type =  0xE0;
++				unsigned char snap_8022_type = 0xAA;
++
++				if(*framePtr == snap_8022_type)
++				{
++					unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37};		// IPX SNAP ID
++					unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3};	// Apple Talk AARP SNAP ID
++					unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B};	// Apple Talk DDP SNAP ID
++
++					framePtr += 3;	// eliminate the 802.2 header
++
++					if(!memcmp(ipx_snap_id, framePtr, 5))
++					{
++						framePtr += 5;	// eliminate the SNAP header
++
++						DEBUG_INFO("NAT25: Protocol=IPX (Ethernet SNAP)\n");
++						ipx = (struct ipxhdr *)framePtr;
++					}
++					else if(!memcmp(aarp_snap_id, framePtr, 5))
++					{
++						framePtr += 5;	// eliminate the SNAP header
++
++						ea = (struct elapaarp *)framePtr;
++					}
++					else if(!memcmp(ddp_snap_id, framePtr, 5))
++					{
++						framePtr += 5;	// eliminate the SNAP header
++
++						ddp = (struct ddpehdr *)framePtr;
++					}
++					else
++					{
++						DEBUG_WARN("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0],
++							framePtr[1], framePtr[2], framePtr[3], framePtr[4]);
++						return -1;
++					}
++				}
++				else if(*framePtr == ipx_8022_type)
++				{
++					framePtr += 3;	// eliminate the 802.2 header
++
++					if(!memcmp(ipx_header, framePtr, 2))
++					{
++						DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.2)\n");
++						ipx = (struct ipxhdr *)framePtr;
++					}
++					else
++						return -1;
++				}
++				else
++					return -1;
++			}
++		}
++		else
++			return -1;
++
++		/*   IPX   */
++		if(ipx != NULL)
++		{
++			switch(method)
++			{
++				case NAT25_CHECK:
++					if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN))
++					{
++						DEBUG_INFO("NAT25: Check IPX skb_copy\n");
++						return 0;
++					}
++					return -1;
++
++				case NAT25_INSERT:
++					{
++						DEBUG_INFO("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n",
++							ipx->ipx_dest.net,
++							ipx->ipx_dest.node[0],
++							ipx->ipx_dest.node[1],
++							ipx->ipx_dest.node[2],
++							ipx->ipx_dest.node[3],
++							ipx->ipx_dest.node[4],
++							ipx->ipx_dest.node[5],
++							ipx->ipx_dest.sock,
++							ipx->ipx_source.net,
++							ipx->ipx_source.node[0],
++							ipx->ipx_source.node[1],
++							ipx->ipx_source.node[2],
++							ipx->ipx_source.node[3],
++							ipx->ipx_source.node[4],
++							ipx->ipx_source.node[5],
++							ipx->ipx_source.sock);
++
++						if(!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN))
++						{
++							DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n");
++
++							__nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock);
++
++							// change IPX source node addr to wlan STA address
++                                                        memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN);
++						}
++						else
++						{
++							__nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node);
++						}
++
++						__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++
++						__nat25_db_print(priv);
++					}
++					return 0;
++
++				case NAT25_LOOKUP:
++					{
++                                                if(!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN))
++						{
++							DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n");
++
++							__nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock);
++
++							__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
++
++							// replace IPX destination node addr with Lookup destination MAC addr
++							memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN);
++						}
++						else
++						{
++							__nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node);
++
++							__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
++						}
++					}
++					return 0;
++
++				default:
++					return -1;
++			}
++		}
++
++		/*   AARP   */
++		else if(ea != NULL)
++		{
++			/* Sanity check fields. */
++			if(ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN)
++			{
++				DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n");
++				return -1;
++			}
++
++			switch(method)
++			{
++				case NAT25_CHECK:
++					return 0;
++
++				case NAT25_INSERT:
++					{
++						// change to AARP source mac address to wlan STA address
++                                                memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN);
++
++						DEBUG_INFO("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n",
++							ea->pa_src_net,
++							ea->pa_src_node,
++							ea->pa_dst_net,
++							ea->pa_dst_node);
++
++						__nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node);
++
++						__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++
++						__nat25_db_print(priv);
++					}
++					return 0;
++
++				case NAT25_LOOKUP:
++					{
++						DEBUG_INFO("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n",
++							ea->pa_src_net,
++							ea->pa_src_node,
++							ea->pa_dst_net,
++							ea->pa_dst_node);
++
++						__nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node);
++
++						__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
++
++						// change to AARP destination mac address to Lookup result
++						memcpy(ea->hw_dst, skb->data, ETH_ALEN);
++					}
++					return 0;
++
++				default:
++					return -1;
++			}
++		}
++
++		/*   DDP   */
++		else if(ddp != NULL)
++		{
++			switch(method)
++			{
++				case NAT25_CHECK:
++					return -1;
++
++				case NAT25_INSERT:
++					{
++						DEBUG_INFO("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n",
++							ddp->deh_snet,
++							ddp->deh_snode,
++							ddp->deh_dnet,
++							ddp->deh_dnode);
++
++						__nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode);
++
++						__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++
++						__nat25_db_print(priv);
++					}
++					return 0;
++
++				case NAT25_LOOKUP:
++					{
++						DEBUG_INFO("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n",
++							ddp->deh_snet,
++							ddp->deh_snode,
++							ddp->deh_dnet,
++							ddp->deh_dnode);
++
++						__nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode);
++
++						__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
++					}
++					return 0;
++
++				default:
++					return -1;
++			}
++		}
++
++		return -1;
++	}
++
++	/*---------------------------------------------------*/
++	/*                Handle PPPoE frame                 */
++	/*---------------------------------------------------*/
++	else if((protocol == __constant_htons(ETH_P_PPP_DISC)) ||
++		(protocol == __constant_htons(ETH_P_PPP_SES)))
++	{
++		struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN);
++		unsigned short *pMagic;
++
++		switch(method)
++		{
++			case NAT25_CHECK:
++				if (ph->sid == 0)
++					return 0;
++				return 1;
++
++			case NAT25_INSERT:
++				if(ph->sid == 0)	// Discovery phase according to tag
++				{
++					if(ph->code == PADI_CODE || ph->code == PADR_CODE)
++					{
++						if (priv->ethBrExtInfo.addPPPoETag) {
++							struct pppoe_tag *tag, *pOldTag;
++							unsigned char tag_buf[40];
++							int old_tag_len=0;
++
++							tag = (struct pppoe_tag *)tag_buf;
++							pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID));
++							if (pOldTag) { // if SID existed, copy old value and delete it
++								old_tag_len = ntohs(pOldTag->tag_len);
++								if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) {
++									DEBUG_ERR("SID tag length too long!\n");
++									return -1;
++								}
++
++								memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN,
++									pOldTag->tag_data, old_tag_len);
++
++								if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) {
++									DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n");
++									return -1;
++								}
++								ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len);
++							}
++
++							tag->tag_type = PTT_RELAY_SID;
++							tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len);
++
++							// insert the magic_code+client mac in relay tag
++							pMagic = (unsigned short *)tag->tag_data;
++							*pMagic = htons(MAGIC_CODE);
++							memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN);
++
++							//Add relay tag
++							if(__nat25_add_pppoe_tag(skb, tag) < 0)
++								return -1;
++
++							DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n",
++											(ph->code == PADI_CODE ? "PADI" : "PADR"));
++						}
++						else { // not add relay tag
++							if (priv->pppoe_connection_in_progress &&
++									memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN))	 {
++								DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n");
++								return -2;
++							}
++
++							if (priv->pppoe_connection_in_progress == 0)
++								memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN);
++
++							priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
++						}
++					}
++					else
++						return -1;
++				}
++				else	// session phase
++				{
++						DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name);
++
++						__nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid));
++
++						__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++
++						__nat25_db_print(priv);
++
++						if (!priv->ethBrExtInfo.addPPPoETag &&
++								priv->pppoe_connection_in_progress &&
++									!memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN))
++							priv->pppoe_connection_in_progress = 0;
++				}
++				return 0;
++
++			case NAT25_LOOKUP:
++				if(ph->code == PADO_CODE || ph->code == PADS_CODE)
++				{
++					if (priv->ethBrExtInfo.addPPPoETag) {
++						struct pppoe_tag *tag;
++						unsigned char *ptr;
++						unsigned short tagType, tagLen;
++						int offset=0;
++
++						if((ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID))) == 0) {
++							DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n");
++							return -1;
++						}
++
++						tag = (struct pppoe_tag *)ptr;
++						tagType = (unsigned short)((ptr[0] << 8) + ptr[1]);
++						tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]);
++
++						if((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) {
++							DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen);
++							return -1;
++						}
++
++						pMagic = (unsigned short *)tag->tag_data;
++						if (ntohs(*pMagic) != MAGIC_CODE) {
++							DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n",
++								(ph->code == PADO_CODE ? "PADO" : "PADS"));
++							return -1;
++						}
++
++						memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN);
++
++						if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN)
++							offset = TAG_HDR_LEN;
++
++						if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) {
++							DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n");
++							return -1;
++						}
++						ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset));
++						if (offset > 0)
++							tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN);
++
++						DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n",
++							(ph->code == PADO_CODE ? "PADO" : "PADS"),	skb->dev->name);
++					}
++					else { // not add relay tag
++						if (!priv->pppoe_connection_in_progress) {
++							DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n");
++							return -1;
++						}
++						memcpy(skb->data, priv->pppoe_addr, ETH_ALEN);
++						priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE;
++					}
++				}
++				else {
++					if(ph->sid != 0)
++					{
++						DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name);
++						__nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid));
++
++						__nat25_db_network_lookup_and_replace(priv, skb, networkAddr);
++
++						__nat25_db_print(priv);
++					}
++					else
++						return -1;
++
++				}
++				return 0;
++
++			default:
++				return -1;
++		}
++	}
++
++	/*---------------------------------------------------*/
++	/*                 Handle EAP frame                  */
++	/*---------------------------------------------------*/
++	else if(protocol == __constant_htons(0x888e))
++	{
++		switch(method)
++		{
++			case NAT25_CHECK:
++				return -1;
++
++			case NAT25_INSERT:
++				return 0;
++
++			case NAT25_LOOKUP:
++				return 0;
++
++			default:
++				return -1;
++		}
++	}
++
++	/*---------------------------------------------------*/
++	/*         Handle C-Media proprietary frame          */
++	/*---------------------------------------------------*/
++	else if((protocol == __constant_htons(0xe2ae)) ||
++		(protocol == __constant_htons(0xe2af)))
++	{
++		switch(method)
++		{
++			case NAT25_CHECK:
++				return -1;
++
++			case NAT25_INSERT:
++				return 0;
++
++			case NAT25_LOOKUP:
++				return 0;
++
++			default:
++				return -1;
++		}
++	}
++
++	/*---------------------------------------------------*/
++	/*         Handle IPV6 frame      							  */
++	/*---------------------------------------------------*/
++#ifdef CL_IPV6_PASS
++	else if(protocol == __constant_htons(ETH_P_IPV6))
++	{
++		struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN);
++
++		if (sizeof(*iph) >= (skb->len - ETH_HLEN))
++		{
++			DEBUG_WARN("NAT25: malformed IPv6 packet !\n");
++			return -1;
++		}
++
++		switch(method)
++		{
++			case NAT25_CHECK:
++				if (skb->data[0] & 1)
++					return 0;
++				return -1;
++
++			case NAT25_INSERT:
++				{
++					DEBUG_INFO("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x,"
++									" DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
++						iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3],
++						iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7],
++						iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3],
++						iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]);
++
++					if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) {
++						__nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr);
++						__nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr);
++						__nat25_db_print(priv);
++
++						if (iph->nexthdr == IPPROTO_ICMPV6 &&
++								skb->len > (ETH_HLEN +  sizeof(*iph) + 4)) {
++							if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph),
++                                                                skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) {
++								struct icmp6hdr  *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph));
++								hdr->icmp6_cksum = 0;
++								hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr,
++												iph->payload_len,
++												IPPROTO_ICMPV6,
++												csum_partial((__u8 *)hdr, iph->payload_len, 0));
++							}
++						}
++					}
++				}
++				return 0;
++
++			case NAT25_LOOKUP:
++				DEBUG_INFO("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x,"
++								" DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n",
++						iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3],
++						iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7],
++						iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3],
++						iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]);
++
++
++				__nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr);
++				if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) {
++#ifdef SUPPORT_RX_UNI2MCAST
++					if (iph->daddr.s6_addr[0] == 0xff)
++						convert_ipv6_mac_to_mc(skb);
++#endif
++				}
++				return 0;
++
++			default:
++				return -1;
++		}
++	}
++#endif	// CL_IPV6_PASS
++
++	return -1;
++}
++
++
++int nat25_handle_frame(_adapter *priv, struct sk_buff *skb)
++{
++#ifdef BR_EXT_DEBUG
++	if((!priv->ethBrExtInfo.nat25_disable) && (!(skb->data[0] & 1)))
++	{
++		panic_printk("NAT25: Input Frame: DA=%02x%02x%02x%02x%02x%02x SA=%02x%02x%02x%02x%02x%02x\n",
++			skb->data[0],
++			skb->data[1],
++			skb->data[2],
++			skb->data[3],
++			skb->data[4],
++			skb->data[5],
++			skb->data[6],
++			skb->data[7],
++			skb->data[8],
++			skb->data[9],
++			skb->data[10],
++			skb->data[11]);
++	}
++#endif
++
++	if(!(skb->data[0] & 1))
++	{
++		int is_vlan_tag=0, i, retval=0;
++		unsigned short vlan_hdr=0;
++
++		if (*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_8021Q)) {
++			is_vlan_tag = 1;
++			vlan_hdr = *((unsigned short *)(skb->data+ETH_ALEN*2+2));
++			for (i=0; i<6; i++)
++				*((unsigned short *)(skb->data+ETH_ALEN*2+2-i*2)) = *((unsigned short *)(skb->data+ETH_ALEN*2-2-i*2));
++			skb_pull(skb, 4);
++		}
++
++		if (!priv->ethBrExtInfo.nat25_disable)
++		{
++			_irqL irqL;
++			_enter_critical_bh(&priv->br_ext_lock, &irqL);
++			/*
++			 *	This function look up the destination network address from
++			 *	the NAT2.5 database. Return value = -1 means that the
++			 *	corresponding network protocol is NOT support.
++			 */
++			if (!priv->ethBrExtInfo.nat25sc_disable &&
++				(*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_IP)) &&
++				!memcmp(priv->scdb_ip, skb->data+ETH_HLEN+16, 4)) {
++				memcpy(skb->data, priv->scdb_mac, ETH_ALEN);
++
++				_exit_critical_bh(&priv->br_ext_lock, &irqL);
++			}
++			else {
++				_exit_critical_bh(&priv->br_ext_lock, &irqL);
++
++				retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
++			}
++		}
++		else {
++			if (((*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_IP)) &&
++					!memcmp(priv->br_ip, skb->data+ETH_HLEN+16, 4)) ||
++				((*((unsigned short *)(skb->data+ETH_ALEN*2)) == __constant_htons(ETH_P_ARP)) &&
++					!memcmp(priv->br_ip, skb->data+ETH_HLEN+24, 4))) {
++				// for traffic to upper TCP/IP
++				retval = nat25_db_handle(priv, skb, NAT25_LOOKUP);
++			}
++		}
++
++		if (is_vlan_tag) {
++			skb_push(skb, 4);
++			for (i=0; i<6; i++)
++				*((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2));
++			*((unsigned short *)(skb->data+ETH_ALEN*2)) = __constant_htons(ETH_P_8021Q);
++			*((unsigned short *)(skb->data+ETH_ALEN*2+2)) = vlan_hdr;
++		}
++
++		if(retval == -1) {
++			//DEBUG_ERR("NAT25: Lookup fail!\n");
++			return -1;
++		}
++	}
++
++	return 0;
++}
++
++#if 0
++void mac_clone(_adapter *priv, unsigned char *addr)
++{
++	struct sockaddr sa;
++
++	memcpy(sa.sa_data, addr, ETH_ALEN);
++	DEBUG_INFO("MAC Clone: Addr=%02x%02x%02x%02x%02x%02x\n",
++		addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
++	rtl8192cd_set_hwaddr(priv->dev, &sa);
++}
++
++
++int mac_clone_handle_frame(_adapter *priv, struct sk_buff *skb)
++{
++	if(priv->ethBrExtInfo.macclone_enable && !priv->macclone_completed)
++	{
++		if(!(skb->data[ETH_ALEN] & 1))	//// check any other particular MAC add
++		{
++                        if(memcmp(skb->data+ETH_ALEN, GET_MY_HWADDR(priv), ETH_ALEN) &&
++				((priv->dev->br_port) &&
++				 memcmp(skb->data+ETH_ALEN, priv->br_mac, ETH_ALEN)))
++			{
++				mac_clone(priv, skb->data+ETH_ALEN);
++				priv->macclone_completed = 1;
++			}
++		}
++	}
++
++	return 0;
++}
++#endif // 0
++
++#define SERVER_PORT			67
++#define CLIENT_PORT			68
++#define DHCP_MAGIC			0x63825363
++#define BROADCAST_FLAG		0x8000
++
++struct dhcpMessage {
++	u_int8_t op;
++	u_int8_t htype;
++	u_int8_t hlen;
++	u_int8_t hops;
++	u_int32_t xid;
++	u_int16_t secs;
++	u_int16_t flags;
++	u_int32_t ciaddr;
++	u_int32_t yiaddr;
++	u_int32_t siaddr;
++	u_int32_t giaddr;
++	u_int8_t chaddr[16];
++	u_int8_t sname[64];
++	u_int8_t file[128];
++	u_int32_t cookie;
++	u_int8_t options[308]; /* 312 - cookie */
++};
++
++void dhcp_flag_bcast(_adapter *priv, struct sk_buff *skb)
++{
++	if(skb == NULL)
++		return;
++
++	if(!priv->ethBrExtInfo.dhcp_bcst_disable)
++	{
++		unsigned short protocol = *((unsigned short *)(skb->data + 2 * ETH_ALEN));
++
++		if(protocol == __constant_htons(ETH_P_IP)) // IP
++		{
++			struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN);
++
++			if(iph->protocol == IPPROTO_UDP) // UDP
++			{
++				struct udphdr *udph = (struct udphdr *)((SIZE_PTR)iph + (iph->ihl << 2));
++
++				if((udph->source == __constant_htons(CLIENT_PORT))
++					&& (udph->dest == __constant_htons(SERVER_PORT))) // DHCP request
++				{
++					struct dhcpMessage *dhcph =
++						(struct dhcpMessage *)((SIZE_PTR)udph + sizeof(struct udphdr));
++
++					if(dhcph->cookie == __constant_htonl(DHCP_MAGIC)) // match magic word
++					{
++						if(!(dhcph->flags & htons(BROADCAST_FLAG))) // if not broadcast
++						{
++							register int sum = 0;
++
++							DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n");
++							// or BROADCAST flag
++							dhcph->flags |= htons(BROADCAST_FLAG);
++							// recalculate checksum
++							sum = ~(udph->check) & 0xffff;
++							sum += dhcph->flags;
++							while(sum >> 16)
++								sum = (sum & 0xffff) + (sum >> 16);
++							udph->check = ~sum;
++						}
++					}
++				}
++			}
++		}
++	}
++}
++
++
++void *scdb_findEntry(_adapter *priv, unsigned char *macAddr,
++				unsigned char *ipAddr)
++{
++	unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
++	struct nat25_network_db_entry *db;
++	int hash;
++	//_irqL irqL;
++	//_enter_critical_bh(&priv->br_ext_lock, &irqL);
++
++	__nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr);
++	hash = __nat25_network_hash(networkAddr);
++	db = priv->nethash[hash];
++	while (db != NULL)
++	{
++		if(!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) {
++			//_exit_critical_bh(&priv->br_ext_lock, &irqL);
++			return (void *)db;
++		}
++
++		db = db->next_hash;
++	}
++
++	//_exit_critical_bh(&priv->br_ext_lock, &irqL);
++	return NULL;
++}
++
++#endif	// CONFIG_BR_EXT
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_cmd.c
+@@ -0,0 +1,3034 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_CMD_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <recv_osdep.h>
++#include <cmd_osdep.h>
++#include <mlme_osdep.h>
++#include <rtw_byteorder.h>
++#ifdef CONFIG_BR_EXT
++#include <rtw_br_ext.h>
++#endif //CONFIG_BR_EXT
++/*
++Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
++No irqsave is necessary.
++*/
++
++sint	_rtw_init_cmd_priv (struct	cmd_priv *pcmdpriv)
++{
++	sint res=_SUCCESS;
++
++_func_enter_;
++
++	_rtw_init_sema(&(pcmdpriv->cmd_queue_sema), 0);
++	//_rtw_init_sema(&(pcmdpriv->cmd_done_sema), 0);
++	_rtw_init_sema(&(pcmdpriv->terminate_cmdthread_sema), 0);
++
++
++	_rtw_init_queue(&(pcmdpriv->cmd_queue));
++
++	//allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf
++
++	pcmdpriv->cmd_seq = 1;
++
++	pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
++
++	if (pcmdpriv->cmd_allocated_buf == NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf  +  CMDBUFF_ALIGN_SZ - ( (SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1));
++
++	pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4);
++
++	if (pcmdpriv->rsp_allocated_buf == NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf  +  4 - ( (SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3);
++
++	pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0;
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++#ifdef CONFIG_C2H_WK
++static void c2h_wk_callback(_workitem *work);
++#endif
++sint _rtw_init_evt_priv(struct evt_priv *pevtpriv)
++{
++	sint res=_SUCCESS;
++
++_func_enter_;
++
++#ifdef CONFIG_H2CLBK
++	_rtw_init_sema(&(pevtpriv->lbkevt_done), 0);
++	pevtpriv->lbkevt_limit = 0;
++	pevtpriv->lbkevt_num = 0;
++	pevtpriv->cmdevt_parm = NULL;
++#endif
++
++	//allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf
++	ATOMIC_SET(&pevtpriv->event_seq, 0);
++	pevtpriv->evt_done_cnt = 0;
++
++#ifdef CONFIG_EVENT_THREAD_MODE
++
++	_rtw_init_sema(&(pevtpriv->evt_notify), 0);
++	_rtw_init_sema(&(pevtpriv->terminate_evtthread_sema), 0);
++
++	pevtpriv->evt_allocated_buf = rtw_zmalloc(MAX_EVTSZ + 4);
++	if (pevtpriv->evt_allocated_buf == NULL){
++		res= _FAIL;
++		goto exit;
++		}
++	pevtpriv->evt_buf = pevtpriv->evt_allocated_buf  +  4 - ((unsigned int)(pevtpriv->evt_allocated_buf) & 3);
++
++
++#ifdef CONFIG_SDIO_HCI
++	pevtpriv->allocated_c2h_mem = rtw_zmalloc(C2H_MEM_SZ +4);
++
++	if (pevtpriv->allocated_c2h_mem == NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pevtpriv->c2h_mem = pevtpriv->allocated_c2h_mem +  4\
++	- ( (u32)(pevtpriv->allocated_c2h_mem) & 3);
++#ifdef PLATFORM_OS_XP
++	pevtpriv->pc2h_mdl= IoAllocateMdl((u8 *)pevtpriv->c2h_mem, C2H_MEM_SZ , FALSE, FALSE, NULL);
++
++	if(pevtpriv->pc2h_mdl == NULL){
++		res= _FAIL;
++		goto exit;
++	}
++	MmBuildMdlForNonPagedPool(pevtpriv->pc2h_mdl);
++#endif
++#endif //end of CONFIG_SDIO_HCI
++
++	_rtw_init_queue(&(pevtpriv->evt_queue));
++
++exit:
++
++#endif //end of CONFIG_EVENT_THREAD_MODE
++
++#ifdef CONFIG_C2H_WK
++	_init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL);
++	pevtpriv->c2h_wk_alive = _FALSE;
++	pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1);
++#endif
++
++_func_exit_;
++
++	return res;
++}
++
++void _rtw_free_evt_priv (struct	evt_priv *pevtpriv)
++{
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("+_rtw_free_evt_priv \n"));
++
++#ifdef CONFIG_EVENT_THREAD_MODE
++	_rtw_free_sema(&(pevtpriv->evt_notify));
++	_rtw_free_sema(&(pevtpriv->terminate_evtthread_sema));
++
++
++	if (pevtpriv->evt_allocated_buf)
++		rtw_mfree(pevtpriv->evt_allocated_buf, MAX_EVTSZ + 4);
++#endif
++
++#ifdef CONFIG_C2H_WK
++	_cancel_workitem_sync(&pevtpriv->c2h_wk);
++	while(pevtpriv->c2h_wk_alive)
++		rtw_msleep_os(10);
++
++	while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) {
++		void *c2h;
++		if ((c2h = rtw_cbuf_pop(pevtpriv->c2h_queue)) != NULL
++			&& c2h != (void *)pevtpriv) {
++			rtw_mfree(c2h, 16);
++		}
++	}
++	rtw_cbuf_free(pevtpriv->c2h_queue);
++#endif
++
++	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n"));
++
++_func_exit_;
++
++}
++
++void _rtw_free_cmd_priv (struct	cmd_priv *pcmdpriv)
++{
++_func_enter_;
++
++	if(pcmdpriv){
++		_rtw_spinlock_free(&(pcmdpriv->cmd_queue.lock));
++		_rtw_free_sema(&(pcmdpriv->cmd_queue_sema));
++		//_rtw_free_sema(&(pcmdpriv->cmd_done_sema));
++		_rtw_free_sema(&(pcmdpriv->terminate_cmdthread_sema));
++
++		if (pcmdpriv->cmd_allocated_buf)
++			rtw_mfree(pcmdpriv->cmd_allocated_buf, MAX_CMDSZ + CMDBUFF_ALIGN_SZ);
++
++		if (pcmdpriv->rsp_allocated_buf)
++			rtw_mfree(pcmdpriv->rsp_allocated_buf, MAX_RSPSZ + 4);
++	}
++_func_exit_;
++}
++
++/*
++Calling Context:
++
++rtw_enqueue_cmd can only be called between kernel thread,
++since only spin_lock is used.
++
++ISR/Call-Back functions can't call this sub-function.
++
++*/
++
++sint	_rtw_enqueue_cmd(_queue *queue, struct cmd_obj *obj)
++{
++	_irqL irqL;
++
++_func_enter_;
++
++	if (obj == NULL)
++		goto exit;
++
++	//_enter_critical_bh(&queue->lock, &irqL);
++	_enter_critical(&queue->lock, &irqL);
++
++	rtw_list_insert_tail(&obj->list, &queue->queue);
++
++	//_exit_critical_bh(&queue->lock, &irqL);
++	_exit_critical(&queue->lock, &irqL);
++
++exit:
++
++_func_exit_;
++
++	return _SUCCESS;
++}
++
++struct	cmd_obj	*_rtw_dequeue_cmd(_queue *queue)
++{
++	_irqL irqL;
++	struct cmd_obj *obj;
++
++_func_enter_;
++
++	//_enter_critical_bh(&(queue->lock), &irqL);
++	_enter_critical(&queue->lock, &irqL);
++	if (rtw_is_list_empty(&(queue->queue)))
++		obj = NULL;
++	else
++	{
++		obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list);
++		rtw_list_delete(&obj->list);
++	}
++
++	//_exit_critical_bh(&(queue->lock), &irqL);
++	_exit_critical(&queue->lock, &irqL);
++
++_func_exit_;
++
++	return obj;
++}
++
++u32	rtw_init_cmd_priv(struct cmd_priv *pcmdpriv)
++{
++	u32	res;
++_func_enter_;
++	res = _rtw_init_cmd_priv (pcmdpriv);
++_func_exit_;
++	return res;
++}
++
++u32	rtw_init_evt_priv (struct	evt_priv *pevtpriv)
++{
++	int	res;
++_func_enter_;
++	res = _rtw_init_evt_priv(pevtpriv);
++_func_exit_;
++	return res;
++}
++
++void rtw_free_evt_priv (struct	evt_priv *pevtpriv)
++{
++_func_enter_;
++	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_evt_priv\n"));
++	_rtw_free_evt_priv(pevtpriv);
++_func_exit_;
++}
++
++void rtw_free_cmd_priv (struct	cmd_priv *pcmdpriv)
++{
++_func_enter_;
++	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("rtw_free_cmd_priv\n"));
++	_rtw_free_cmd_priv(pcmdpriv);
++_func_exit_;
++}
++
++int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj);
++int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
++{
++	u8 bAllow = _FALSE; //set to _TRUE to allow enqueuing cmd when hw_init_completed is _FALSE
++
++	#ifdef SUPPORT_HW_RFOFF_DETECTED
++	//To decide allow or not
++	if(	(pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect)
++		&&(!pcmdpriv->padapter->registrypriv.usbss_enable)
++	)
++	{
++		if(cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra) )
++		{
++			struct drvextra_cmd_parm	*pdrvextra_cmd_parm = (struct drvextra_cmd_parm	*)cmd_obj->parmbuf;
++			if(pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID)
++			{
++				//DBG_871X("==>enqueue POWER_SAVING_CTRL_WK_CID\n");
++				bAllow = _TRUE;
++			}
++		}
++	}
++	#endif
++
++	if(cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan))
++		bAllow = _TRUE;
++
++	if( (pcmdpriv->padapter->hw_init_completed ==_FALSE && bAllow == _FALSE)
++		|| pcmdpriv->cmdthd_running== _FALSE	//com_thread not running
++	)
++	{
++		//DBG_871X("%s:%s: drop cmdcode:%u, hw_init_completed:%u, cmdthd_running:%u\n", caller_func, __FUNCTION__,
++		//	cmd_obj->cmdcode,
++		//	pcmdpriv->padapter->hw_init_completed,
++		//	pcmdpriv->cmdthd_running
++		//);
++
++		return _FAIL;
++	}
++	return _SUCCESS;
++}
++
++
++
++u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
++{
++	int res = _FAIL;
++	PADAPTER padapter = pcmdpriv->padapter;
++
++_func_enter_;
++
++	if (cmd_obj == NULL) {
++		goto exit;
++	}
++
++	cmd_obj->padapter = padapter;
++
++#ifdef CONFIG_CONCURRENT_MODE
++	//change pcmdpriv to primary's pcmdpriv
++	if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter)
++		pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv);
++#endif
++
++	if( _FAIL == (res=rtw_cmd_filter(pcmdpriv, cmd_obj)) ) {
++		rtw_free_cmd_obj(cmd_obj);
++		goto exit;
++	}
++
++	res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj);
++
++	if(res == _SUCCESS)
++		_rtw_up_sema(&pcmdpriv->cmd_queue_sema);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++struct	cmd_obj	*rtw_dequeue_cmd(struct cmd_priv *pcmdpriv)
++{
++	struct cmd_obj *cmd_obj;
++
++_func_enter_;
++
++	cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue);
++
++_func_exit_;
++	return cmd_obj;
++}
++
++void rtw_cmd_clr_isr(struct	cmd_priv *pcmdpriv)
++{
++_func_enter_;
++	pcmdpriv->cmd_done_cnt++;
++	//_rtw_up_sema(&(pcmdpriv->cmd_done_sema));
++_func_exit_;
++}
++
++void rtw_free_cmd_obj(struct cmd_obj *pcmd)
++{
++_func_enter_;
++
++	if((pcmd->cmdcode!=_JoinBss_CMD_) &&(pcmd->cmdcode!= _CreateBss_CMD_))
++	{
++		//free parmbuf in cmd_obj
++		rtw_mfree((unsigned char*)pcmd->parmbuf, pcmd->cmdsz);
++	}
++
++	if(pcmd->rsp!=NULL)
++	{
++		if(pcmd->rspsz!= 0)
++		{
++			//free rsp in cmd_obj
++			rtw_mfree((unsigned char*)pcmd->rsp, pcmd->rspsz);
++		}
++	}
++
++	//free cmd_obj
++	rtw_mfree((unsigned char*)pcmd, sizeof(struct cmd_obj));
++
++_func_exit_;
++}
++
++void rtw_stop_cmd_thread(_adapter *adapter)
++{
++	if(adapter->cmdThread && adapter->cmdpriv.cmdthd_running == _TRUE
++		&& adapter->cmdpriv.stop_req == 0)
++	{
++		adapter->cmdpriv.stop_req = 1;
++		_rtw_up_sema(&adapter->cmdpriv.cmd_queue_sema);
++		_rtw_down_sema(&adapter->cmdpriv.terminate_cmdthread_sema);
++	}
++}
++
++thread_return rtw_cmd_thread(thread_context context)
++{
++	u8 ret;
++	struct cmd_obj *pcmd;
++	u8 *pcmdbuf, *prspbuf;
++	u8 (*cmd_hdl)(_adapter *padapter, u8* pbuf);
++	void (*pcmd_callback)(_adapter *dev, struct cmd_obj *pcmd);
++       _adapter *padapter = (_adapter *)context;
++	struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
++
++_func_enter_;
++
++	thread_enter("RTW_CMD_THREAD");
++
++	pcmdbuf = pcmdpriv->cmd_buf;
++	prspbuf = pcmdpriv->rsp_buf;
++
++	pcmdpriv->stop_req = 0;
++	pcmdpriv->cmdthd_running=_TRUE;
++	_rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema);
++
++	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("start r871x rtw_cmd_thread !!!!\n"));
++
++	while(1)
++	{
++		if ((_rtw_down_sema(&(pcmdpriv->cmd_queue_sema))) == _FAIL) {
++			LOG_LEVEL(_drv_err_, FUNC_ADPT_FMT" _rtw_down_sema(&pcmdpriv->cmd_queue_sema) return _FAIL, break\n", FUNC_ADPT_ARG(padapter));
++			break;
++		}
++
++		if (pcmdpriv->stop_req) {
++			LOG_LEVEL(_drv_err_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req);
++			break;
++		}
++
++#ifdef CONFIG_LPS_LCLK
++		if (rtw_register_cmd_alive(padapter) != _SUCCESS)
++		{
++			continue;
++		}
++#endif
++
++_next:
++		if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved == _TRUE))
++		{
++			LOG_LEVEL(_drv_err_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
++				__FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
++			break;
++		}
++
++		if(!(pcmd = rtw_dequeue_cmd(pcmdpriv))) {
++#ifdef CONFIG_LPS_LCLK
++			rtw_unregister_cmd_alive(padapter);
++#endif
++			continue;
++		}
++
++		if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) )
++		{
++			pcmd->res = H2C_DROPPED;
++			goto post_process;
++		}
++
++		if( _FAIL == rtw_cmd_filter(pcmdpriv, pcmd) ) {
++			rtw_free_cmd_obj(pcmd);
++			continue;
++		}
++
++		pcmdpriv->cmd_issued_cnt++;
++
++		pcmd->cmdsz = _RND4((pcmd->cmdsz));//_RND4
++
++		_rtw_memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz);
++
++		if(pcmd->cmdcode <= (sizeof(wlancmds) /sizeof(struct cmd_hdl)))
++		{
++			cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns;
++
++			if (cmd_hdl)
++			{
++				ret = cmd_hdl(pcmd->padapter, pcmdbuf);
++				pcmd->res = ret;
++			}
++
++			pcmdpriv->cmd_seq++;
++		}
++		else
++		{
++			pcmd->res = H2C_PARAMETERS_ERROR;
++		}
++
++		cmd_hdl = NULL;
++
++post_process:
++
++		//call callback function for post-processed
++		if(pcmd->cmdcode <= (sizeof(rtw_cmd_callback) /sizeof(struct _cmd_callback)))
++		{
++			pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback;
++			if(pcmd_callback == NULL)
++			{
++				RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("mlme_cmd_hdl(): pcmd_callback=0x%p, cmdcode=0x%x\n", pcmd_callback, pcmd->cmdcode));
++				rtw_free_cmd_obj(pcmd);
++			}
++			else
++			{
++				//todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!=NULL)
++				pcmd_callback(pcmd->padapter, pcmd);//need conider that free cmd_obj in rtw_cmd_callback
++			}
++		}
++
++		flush_signals_thread();
++
++		goto _next;
++
++	}
++	pcmdpriv->cmdthd_running=_FALSE;
++
++
++	// free all cmd_obj resources
++	do{
++		pcmd = rtw_dequeue_cmd(pcmdpriv);
++		if(pcmd==NULL)
++			break;
++
++		//DBG_871X("%s: leaving... drop cmdcode:%u\n", __FUNCTION__, pcmd->cmdcode);
++
++		rtw_free_cmd_obj(pcmd);
++	}while(1);
++
++	_rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema);
++
++_func_exit_;
++
++	thread_exit();
++
++}
++
++
++#ifdef CONFIG_EVENT_THREAD_MODE
++u32 rtw_enqueue_evt(struct evt_priv *pevtpriv, struct evt_obj *obj)
++{
++	_irqL irqL;
++	int	res;
++	_queue *queue = &pevtpriv->evt_queue;
++
++_func_enter_;
++
++	res = _SUCCESS;
++
++	if (obj == NULL) {
++		res = _FAIL;
++		goto exit;
++	}
++
++	_enter_critical_bh(&queue->lock, &irqL);
++
++	rtw_list_insert_tail(&obj->list, &queue->queue);
++
++	_exit_critical_bh(&queue->lock, &irqL);
++
++	//rtw_evt_notify_isr(pevtpriv);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++struct evt_obj *rtw_dequeue_evt(_queue *queue)
++{
++	_irqL irqL;
++	struct	evt_obj	*pevtobj;
++
++_func_enter_;
++
++	_enter_critical_bh(&queue->lock, &irqL);
++
++	if (rtw_is_list_empty(&(queue->queue)))
++		pevtobj = NULL;
++	else
++	{
++		pevtobj = LIST_CONTAINOR(get_next(&(queue->queue)), struct evt_obj, list);
++		rtw_list_delete(&pevtobj->list);
++	}
++
++	_exit_critical_bh(&queue->lock, &irqL);
++
++_func_exit_;
++
++	return pevtobj;
++}
++
++void rtw_free_evt_obj(struct evt_obj *pevtobj)
++{
++_func_enter_;
++
++	if(pevtobj->parmbuf)
++		rtw_mfree((unsigned char*)pevtobj->parmbuf, pevtobj->evtsz);
++
++	rtw_mfree((unsigned char*)pevtobj, sizeof(struct evt_obj));
++
++_func_exit_;
++}
++
++void rtw_evt_notify_isr(struct evt_priv *pevtpriv)
++{
++_func_enter_;
++	pevtpriv->evt_done_cnt++;
++	_rtw_up_sema(&(pevtpriv->evt_notify));
++_func_exit_;
++}
++#endif
++
++
++/*
++u8 rtw_setstandby_cmd(unsigned char  *adapter)
++*/
++u8 rtw_setstandby_cmd(_adapter *padapter, uint action)
++{
++	struct cmd_obj*			ph2c;
++	struct usb_suspend_parm*	psetusbsuspend;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++
++	u8 ret = _SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if (ph2c == NULL) {
++		ret = _FAIL;
++		goto exit;
++	}
++
++	psetusbsuspend = (struct usb_suspend_parm*)rtw_zmalloc(sizeof(struct usb_suspend_parm));
++	if (psetusbsuspend == NULL) {
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		ret = _FAIL;
++		goto exit;
++	}
++
++	psetusbsuspend->action = action;
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend));
++
++	ret = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return ret;
++}
++
++/*
++rtw_sitesurvey_cmd(~)
++	### NOTE:#### (!!!!)
++	MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
++*/
++u8 rtw_sitesurvey_cmd(_adapter  *padapter, NDIS_802_11_SSID *ssid, int ssid_num,
++	struct rtw_ieee80211_channel *ch, int ch_num)
++{
++	u8 res = _FAIL;
++	struct cmd_obj		*ph2c;
++	struct sitesurvey_parm	*psurveyPara;
++	struct cmd_priv 	*pcmdpriv = &padapter->cmdpriv;
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++#ifdef CONFIG_LPS
++	if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE){
++		rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1);
++	}
++#endif
++
++#ifdef CONFIG_P2P_PS
++	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
++		p2p_ps_wk_cmd(padapter, P2P_PS_SCAN, 1);
++	}
++#endif // CONFIG_P2P_PS
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if (ph2c == NULL)
++		return _FAIL;
++
++	psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm));
++	if (psurveyPara == NULL) {
++		rtw_mfree((unsigned char*) ph2c, sizeof(struct cmd_obj));
++		return _FAIL;
++	}
++
++	rtw_free_network_queue(padapter, _FALSE);
++
++	RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("\nflush  network queue\n\n"));
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
++
++	/* psurveyPara->bsslimit = 48; */
++	psurveyPara->scan_mode = pmlmepriv->scan_mode;
++
++	/* prepare ssid list */
++	if (ssid) {
++		int i;
++		for (i=0; i<ssid_num && i< RTW_SSID_SCAN_AMOUNT; i++) {
++			if (ssid[i].SsidLength) {
++				_rtw_memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(NDIS_802_11_SSID));
++				psurveyPara->ssid_num++;
++				if (0)
++				DBG_871X(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter),
++					psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength);
++			}
++		}
++	}
++
++	/* prepare channel list */
++	if (ch) {
++		int i;
++		for (i=0; i<ch_num && i< RTW_CHANNEL_SCAN_AMOUNT; i++) {
++			if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) {
++				_rtw_memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel));
++				psurveyPara->ch_num++;
++				if (0)
++				DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter),
++					psurveyPara->ch[i].hw_value);
++			}
++		}
++	}
++
++	set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++	if(res == _SUCCESS) {
++
++		pmlmepriv->scan_start_time = rtw_get_current_time();
++
++#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++		if (padapter->pbuddy_adapter == NULL )
++			goto full_scan_timeout;
++		if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
++			_set_timer(&pmlmepriv->scan_to_timer,
++				SURVEY_TO * ( padapter->mlmeextpriv.max_chan_nums + ( padapter->mlmeextpriv.max_chan_nums  / RTW_SCAN_NUM_OF_CH ) * RTW_STAY_AP_CH_MILLISECOND ) + 1000 );
++		else
++#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++full_scan_timeout:
++			_set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
++
++		rtw_led_control(padapter, LED_CTL_SITE_SURVEY);
++
++		pmlmepriv->scan_interval = SCAN_INTERVAL;// 30*2 sec = 60sec
++	} else {
++		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
++	}
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_setdatarate_cmd(_adapter *padapter, u8 *rateset)
++{
++	struct cmd_obj*			ph2c;
++	struct setdatarate_parm*	pbsetdataratepara;
++	struct cmd_priv*		pcmdpriv = &padapter->cmdpriv;
++	u8	res = _SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if (ph2c == NULL) {
++		res = _FAIL;
++		goto exit;
++	}
++
++	pbsetdataratepara = (struct setdatarate_parm*)rtw_zmalloc(sizeof(struct setdatarate_parm));
++	if (pbsetdataratepara == NULL) {
++		rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
++		res = _FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate));
++#ifdef MP_FIRMWARE_OFFLOAD
++	pbsetdataratepara->curr_rateidx = *(u32*)rateset;
++//	_rtw_memcpy(pbsetdataratepara, rateset, sizeof(u32));
++#else
++	pbsetdataratepara->mac_id = 5;
++	_rtw_memcpy(pbsetdataratepara->datarates, rateset, NumRates);
++#endif
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_setbasicrate_cmd(_adapter *padapter, u8 *rateset)
++{
++	struct cmd_obj*			ph2c;
++	struct setbasicrate_parm*	pssetbasicratepara;
++	struct cmd_priv*		pcmdpriv=&padapter->cmdpriv;
++	u8	res = _SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if (ph2c == NULL) {
++		res= _FAIL;
++		goto exit;
++	}
++	pssetbasicratepara = (struct setbasicrate_parm*)rtw_zmalloc(sizeof(struct setbasicrate_parm));
++
++	if (pssetbasicratepara == NULL) {
++		rtw_mfree((u8*) ph2c, sizeof(struct cmd_obj));
++		res = _FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara, _SetBasicRate_CMD_);
++
++	_rtw_memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++
++/*
++unsigned char rtw_setphy_cmd(unsigned char  *adapter)
++
++1.  be called only after rtw_update_registrypriv_dev_network( ~) or mp testing program
++2.  for AdHoc/Ap mode or mp mode?
++
++*/
++u8 rtw_setphy_cmd(_adapter *padapter, u8 modem, u8 ch)
++{
++	struct cmd_obj*			ph2c;
++	struct setphy_parm*		psetphypara;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++//	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
++//	struct registry_priv*		pregistry_priv = &padapter->registrypriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++		}
++	psetphypara = (struct setphy_parm*)rtw_zmalloc(sizeof(struct setphy_parm));
++
++	if(psetphypara==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_);
++
++	RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("CH=%d, modem=%d", ch, modem));
++
++	psetphypara->modem = modem;
++	psetphypara->rfchannel = ch;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++_func_exit_;
++	return res;
++}
++
++u8 rtw_setbbreg_cmd(_adapter*padapter, u8 offset, u8 val)
++{
++	struct cmd_obj*			ph2c;
++	struct writeBB_parm*		pwritebbparm;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++_func_enter_;
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++		}
++	pwritebbparm = (struct writeBB_parm*)rtw_zmalloc(sizeof(struct writeBB_parm));
++
++	if(pwritebbparm==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg));
++
++	pwritebbparm->offset = offset;
++	pwritebbparm->value = val;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++_func_exit_;
++	return res;
++}
++
++u8 rtw_getbbreg_cmd(_adapter  *padapter, u8 offset, u8 *pval)
++{
++	struct cmd_obj*			ph2c;
++	struct readBB_parm*		prdbbparm;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res=_FAIL;
++		goto exit;
++		}
++	prdbbparm = (struct readBB_parm*)rtw_zmalloc(sizeof(struct readBB_parm));
++
++	if(prdbbparm ==NULL){
++		rtw_mfree((unsigned char *) ph2c, sizeof(struct	cmd_obj));
++		return _FAIL;
++	}
++
++	_rtw_init_listhead(&ph2c->list);
++	ph2c->cmdcode =GEN_CMD_CODE(_GetBBReg);
++	ph2c->parmbuf = (unsigned char *)prdbbparm;
++	ph2c->cmdsz =  sizeof(struct readBB_parm);
++	ph2c->rsp = pval;
++	ph2c->rspsz = sizeof(struct readBB_rsp);
++
++	prdbbparm ->offset = offset;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++_func_exit_;
++	return res;
++}
++
++u8 rtw_setrfreg_cmd(_adapter  *padapter, u8 offset, u32 val)
++{
++	struct cmd_obj*			ph2c;
++	struct writeRF_parm*		pwriterfparm;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++_func_enter_;
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++	pwriterfparm = (struct writeRF_parm*)rtw_zmalloc(sizeof(struct writeRF_parm));
++
++	if(pwriterfparm==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
++
++	pwriterfparm->offset = offset;
++	pwriterfparm->value = val;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++_func_exit_;
++	return res;
++}
++
++u8 rtw_getrfreg_cmd(_adapter  *padapter, u8 offset, u8 *pval)
++{
++	struct cmd_obj*			ph2c;
++	struct readRF_parm*		prdrfparm;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	prdrfparm = (struct readRF_parm*)rtw_zmalloc(sizeof(struct readRF_parm));
++	if(prdrfparm ==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	_rtw_init_listhead(&ph2c->list);
++	ph2c->cmdcode =GEN_CMD_CODE(_GetRFReg);
++	ph2c->parmbuf = (unsigned char *)prdrfparm;
++	ph2c->cmdsz =  sizeof(struct readRF_parm);
++	ph2c->rsp = pval;
++	ph2c->rspsz = sizeof(struct readRF_rsp);
++
++	prdrfparm ->offset = offset;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++void rtw_getbbrfreg_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
++{
++ _func_enter_;
++
++	//rtw_free_cmd_obj(pcmd);
++	rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz);
++	rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj));
++
++#ifdef CONFIG_MP_INCLUDED
++	padapter->mppriv.workparam.bcompleted= _TRUE;
++#endif
++_func_exit_;
++}
++
++void rtw_readtssi_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
++{
++ _func_enter_;
++
++	rtw_mfree((unsigned char*) pcmd->parmbuf, pcmd->cmdsz);
++	rtw_mfree((unsigned char*) pcmd, sizeof(struct cmd_obj));
++
++#ifdef CONFIG_MP_INCLUDED
++	padapter->mppriv.workparam.bcompleted= _TRUE;
++#endif
++
++_func_exit_;
++}
++
++u8 rtw_createbss_cmd(_adapter  *padapter)
++{
++	struct cmd_obj*			pcmd;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
++	WLAN_BSSID_EX		*pdev_network = &padapter->registrypriv.dev_network;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	rtw_led_control(padapter, LED_CTL_START_TO_LINK);
++
++	if (pmlmepriv->assoc_ssid.SsidLength == 0){
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for Any SSid:%s\n",pmlmepriv->assoc_ssid.Ssid));
++	} else {
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,(" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
++	}
++
++	pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(pcmd==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	_rtw_init_listhead(&pcmd->list);
++	pcmd->cmdcode = _CreateBss_CMD_;
++	pcmd->parmbuf = (unsigned char *)pdev_network;
++	pcmd->cmdsz = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX*)pdev_network);
++	pcmd->rsp = NULL;
++	pcmd->rspsz = 0;
++
++	pdev_network->Length = pcmd->cmdsz;
++
++#ifdef CONFIG_RTL8712
++	//notes: translate IELength & Length after assign the Length to cmdsz;
++	pdev_network->Length = cpu_to_le32(pcmd->cmdsz);
++	pdev_network->IELength = cpu_to_le32(pdev_network->IELength);
++	pdev_network->Ssid.SsidLength = cpu_to_le32(pdev_network->Ssid.SsidLength);
++#endif
++
++	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_createbss_cmd_ex(_adapter  *padapter, unsigned char *pbss, unsigned int sz)
++{
++	struct cmd_obj*	pcmd;
++	struct cmd_priv 	*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(pcmd==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	_rtw_init_listhead(&pcmd->list);
++	pcmd->cmdcode = GEN_CMD_CODE(_CreateBss);
++	pcmd->parmbuf = pbss;
++	pcmd->cmdsz =  sz;
++	pcmd->rsp = NULL;
++	pcmd->rspsz = 0;
++
++	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_joinbss_cmd(_adapter  *padapter, struct wlan_network* pnetwork)
++{
++	u8	*auth, res = _SUCCESS;
++	uint	t_len = 0;
++	WLAN_BSSID_EX		*psecnetwork;
++	struct cmd_obj		*pcmd;
++	struct cmd_priv		*pcmdpriv=&padapter->cmdpriv;
++	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
++	struct qos_priv		*pqospriv= &pmlmepriv->qospriv;
++	struct security_priv	*psecuritypriv=&padapter->securitypriv;
++	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
++	struct ht_priv			*phtpriv = &pmlmepriv->htpriv;
++	NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++_func_enter_;
++
++	rtw_led_control(padapter, LED_CTL_START_TO_LINK);
++
++	if (pmlmepriv->assoc_ssid.SsidLength == 0){
++		RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n"));
++	} else {
++		RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid=[%s]\n", pmlmepriv->assoc_ssid.Ssid));
++	}
++
++	pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(pcmd==NULL){
++		res=_FAIL;
++		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
++		goto exit;
++	}
++	/* // for IEs is pointer
++	t_len = sizeof (ULONG) + sizeof (NDIS_802_11_MAC_ADDRESS) + 2 +
++			sizeof (NDIS_802_11_SSID) + sizeof (ULONG) +
++			sizeof (NDIS_802_11_RSSI) + sizeof (NDIS_802_11_NETWORK_TYPE) +
++			sizeof (NDIS_802_11_CONFIGURATION) +
++			sizeof (NDIS_802_11_NETWORK_INFRASTRUCTURE) +
++			sizeof (NDIS_802_11_RATES_EX)+ sizeof(WLAN_PHY_INFO)+ sizeof (ULONG) + MAX_IE_SZ;
++	*/
++	//for IEs is fix buf size
++	t_len = sizeof(WLAN_BSSID_EX);
++
++
++	//for hidden ap to set fw_state here
++	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != _TRUE)
++	{
++		switch(ndis_network_mode)
++		{
++			case Ndis802_11IBSS:
++				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
++				break;
++
++			case Ndis802_11Infrastructure:
++				set_fwstate(pmlmepriv, WIFI_STATION_STATE);
++				break;
++
++			case Ndis802_11APMode:
++			case Ndis802_11AutoUnknown:
++			case Ndis802_11InfrastructureMax:
++				break;
++
++		}
++	}
++
++	psecnetwork=(WLAN_BSSID_EX *)&psecuritypriv->sec_bss;
++	if(psecnetwork==NULL)
++	{
++		if(pcmd !=NULL)
++			rtw_mfree((unsigned char *)pcmd, sizeof(struct	cmd_obj));
++
++		res=_FAIL;
++
++		RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork==NULL!!!\n"));
++
++		goto exit;
++	}
++
++	_rtw_memset(psecnetwork, 0, t_len);
++
++	_rtw_memcpy(psecnetwork, &pnetwork->network, get_WLAN_BSSID_EX_sz(&pnetwork->network));
++
++	auth=&psecuritypriv->authenticator_ie[0];
++	psecuritypriv->authenticator_ie[0]=(unsigned char)psecnetwork->IELength;
++
++	if((psecnetwork->IELength-12) < (256-1)) {
++		_rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12);
++	} else {
++		_rtw_memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1));
++	}
++
++	psecnetwork->IELength = 0;
++	// Added by Albert 2009/02/18
++	// If the the driver wants to use the bssid to create the connection.
++	// If not,  we have to copy the connecting AP's MAC address to it so that
++	// the driver just has the bssid information for PMKIDList searching.
++
++	if ( pmlmepriv->assoc_by_bssid == _FALSE )
++	{
++		_rtw_memcpy( &pmlmepriv->assoc_bssid[ 0 ], &pnetwork->network.MacAddress[ 0 ], ETH_ALEN );
++	}
++
++	psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength);
++
++
++	pqospriv->qos_option = 0;
++
++	if(pregistrypriv->wmm_enable)
++	{
++		u32 tmp_len;
++
++		tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength);
++
++		if (psecnetwork->IELength != tmp_len)
++		{
++			psecnetwork->IELength = tmp_len;
++			pqospriv->qos_option = 1; //There is WMM IE in this corresp. beacon
++		}
++		else
++		{
++			pqospriv->qos_option = 0;//There is no WMM IE in this corresp. beacon
++		}
++	}
++
++#ifdef CONFIG_80211N_HT
++	phtpriv->ht_option = _FALSE;
++	if(pregistrypriv->ht_enable)
++	{
++		//	Added by Albert 2010/06/23
++		//	For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue.
++		//	Especially for Realtek 8192u SoftAP.
++		if (	( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_ ) &&
++			( padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_ ) &&
++			( padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_ ))
++		{
++			//rtw_restructure_ht_ie
++			rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0],
++									pnetwork->network.IELength, &psecnetwork->IELength, (u8)psecnetwork->Configuration.DSConfig );
++		}
++	}
++
++#endif
++
++	pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
++
++	#if 0
++	psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength;
++
++	if(psecnetwork->IELength < (256-1))
++	{
++		_rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], psecnetwork->IELength);
++	}
++	else
++	{
++		_rtw_memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0], (256-1));
++	}
++	#endif
++
++	pcmd->cmdsz = get_WLAN_BSSID_EX_sz(psecnetwork);//get cmdsz before endian conversion
++
++#ifdef CONFIG_RTL8712
++	//wlan_network endian conversion
++	psecnetwork->Length = cpu_to_le32(psecnetwork->Length);
++	psecnetwork->Ssid.SsidLength= cpu_to_le32(psecnetwork->Ssid.SsidLength);
++	psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy);
++	psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi);
++	psecnetwork->NetworkTypeInUse = cpu_to_le32(psecnetwork->NetworkTypeInUse);
++	psecnetwork->Configuration.ATIMWindow = cpu_to_le32(psecnetwork->Configuration.ATIMWindow);
++	psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(psecnetwork->Configuration.BeaconPeriod);
++	psecnetwork->Configuration.DSConfig = cpu_to_le32(psecnetwork->Configuration.DSConfig);
++	psecnetwork->Configuration.FHConfig.DwellTime=cpu_to_le32(psecnetwork->Configuration.FHConfig.DwellTime);
++	psecnetwork->Configuration.FHConfig.HopPattern=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopPattern);
++	psecnetwork->Configuration.FHConfig.HopSet=cpu_to_le32(psecnetwork->Configuration.FHConfig.HopSet);
++	psecnetwork->Configuration.FHConfig.Length=cpu_to_le32(psecnetwork->Configuration.FHConfig.Length);
++	psecnetwork->Configuration.Length = cpu_to_le32(psecnetwork->Configuration.Length);
++	psecnetwork->InfrastructureMode = cpu_to_le32(psecnetwork->InfrastructureMode);
++	psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
++#endif
++
++	_rtw_init_listhead(&pcmd->list);
++	pcmd->cmdcode = _JoinBss_CMD_;//GEN_CMD_CODE(_JoinBss)
++	pcmd->parmbuf = (unsigned char *)psecnetwork;
++	pcmd->rsp = NULL;
++	pcmd->rspsz = 0;
++
++	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_disassoc_cmd(_adapter*padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */
++{
++	struct cmd_obj *cmdobj = NULL;
++	struct disconnect_parm *param = NULL;
++	struct cmd_priv *cmdpriv = &padapter->cmdpriv;
++	u8 res = _SUCCESS;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n"));
++
++	/* prepare cmd parameter */
++	param = (struct disconnect_parm *)rtw_zmalloc(sizeof(*param));
++	if (param == NULL) {
++		res = _FAIL;
++		goto exit;
++	}
++	param->deauth_timeout_ms = deauth_timeout_ms;
++
++	if (enqueue) {
++		/* need enqueue, prepare cmd_obj and enqueue */
++		cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(*cmdobj));
++		if (cmdobj == NULL) {
++			res = _FAIL;
++			rtw_mfree((u8 *)param, sizeof(*param));
++			goto exit;
++		}
++		init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_);
++		res = rtw_enqueue_cmd(cmdpriv, cmdobj);
++	} else {
++		/* no need to enqueue, do the cmd hdl directly and free cmd parameter */
++		if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param))
++			res = _FAIL;
++		rtw_mfree((u8 *)param, sizeof(*param));
++	}
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_setopmode_cmd(_adapter  *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
++{
++	struct	cmd_obj*	ph2c;
++	struct	setopmode_parm* psetop;
++
++	struct	cmd_priv   *pcmdpriv= &padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FALSE;
++		goto exit;
++	}
++	psetop = (struct setopmode_parm*)rtw_zmalloc(sizeof(struct setopmode_parm));
++
++	if(psetop==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res=_FALSE;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
++	psetop->mode = (u8)networktype;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key)
++{
++	struct cmd_obj*			ph2c;
++	struct set_stakey_parm	*psetstakey_para;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	struct set_stakey_rsp		*psetstakey_rsp = NULL;
++
++	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
++	struct security_priv 		*psecuritypriv = &padapter->securitypriv;
++	struct sta_info* 			sta = (struct sta_info* )psta;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if ( ph2c == NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
++	if(psetstakey_para==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res=_FAIL;
++		goto exit;
++	}
++
++	psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
++	if(psetstakey_rsp == NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
++		res=_FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
++	ph2c->rsp = (u8 *) psetstakey_rsp;
++	ph2c->rspsz = sizeof(struct set_stakey_rsp);
++
++	_rtw_memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN);
++
++	if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)){
++#ifdef CONFIG_TDLS
++		if(sta->tdls_sta_state&TDLS_LINKED_STATE)
++			psetstakey_para->algorithm=(u8)sta->dot118021XPrivacy;
++		else
++#endif //CONFIG_TDLS
++		psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
++	}else{
++		GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE);
++	}
++
++	if (unicast_key == _TRUE) {
++#ifdef CONFIG_TDLS
++		if(sta->tdls_sta_state&TDLS_LINKED_STATE)
++			_rtw_memcpy(&psetstakey_para->key, sta->tpk.tk, 16);
++		else
++#endif //CONFIG_TDLS
++			_rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
++        } else {
++		_rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
++        }
++
++	//jeff: set this becasue at least sw key is ready
++	padapter->securitypriv.busetkipkey=_TRUE;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_clearstakey_cmd(_adapter *padapter, u8 *psta, u8 entry, u8 enqueue)
++{
++	struct cmd_obj*			ph2c;
++	struct set_stakey_parm	*psetstakey_para;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	struct set_stakey_rsp		*psetstakey_rsp = NULL;
++	struct mlme_priv			*pmlmepriv = &padapter->mlmepriv;
++	struct security_priv 		*psecuritypriv = &padapter->securitypriv;
++	struct sta_info* 			sta = (struct sta_info* )psta;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	if(!enqueue)
++	{
++		clear_cam_entry(padapter, entry);
++	}
++	else
++	{
++		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++		if ( ph2c == NULL){
++			res= _FAIL;
++			goto exit;
++		}
++
++		psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
++		if(psetstakey_para==NULL){
++			rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++			res=_FAIL;
++			goto exit;
++		}
++
++		psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
++		if(psetstakey_rsp == NULL){
++			rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++			rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
++			res=_FAIL;
++			goto exit;
++		}
++
++		init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
++		ph2c->rsp = (u8 *) psetstakey_rsp;
++		ph2c->rspsz = sizeof(struct set_stakey_rsp);
++
++		_rtw_memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN);
++
++		psetstakey_para->algorithm = _NO_PRIVACY_;
++
++		psetstakey_para->id = entry;
++
++		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++	}
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_setrttbl_cmd(_adapter  *padapter, struct setratable_parm *prate_table)
++{
++	struct cmd_obj*			ph2c;
++	struct setratable_parm *	psetrttblparm;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++		}
++	psetrttblparm = (struct setratable_parm*)rtw_zmalloc(sizeof(struct setratable_parm));
++
++	if(psetrttblparm==NULL){
++		rtw_mfree((unsigned char *) ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
++
++	_rtw_memcpy(psetrttblparm,prate_table,sizeof(struct setratable_parm));
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++_func_exit_;
++	return res;
++
++}
++
++u8 rtw_getrttbl_cmd(_adapter  *padapter, struct getratable_rsp *pval)
++{
++	struct cmd_obj*			ph2c;
++	struct getratable_parm *	pgetrttblparm;
++	struct cmd_priv 			*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++	pgetrttblparm = (struct getratable_parm*)rtw_zmalloc(sizeof(struct getratable_parm));
++
++	if(pgetrttblparm==NULL){
++		rtw_mfree((unsigned char *) ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++//	init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable));
++
++	_rtw_init_listhead(&ph2c->list);
++	ph2c->cmdcode =GEN_CMD_CODE(_GetRaTable);
++	ph2c->parmbuf = (unsigned char *)pgetrttblparm;
++	ph2c->cmdsz =  sizeof(struct getratable_parm);
++	ph2c->rsp = (u8*)pval;
++	ph2c->rspsz = sizeof(struct getratable_rsp);
++
++	pgetrttblparm ->rsvd = 0x0;
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++exit:
++_func_exit_;
++	return res;
++
++}
++
++u8 rtw_setassocsta_cmd(_adapter  *padapter, u8 *mac_addr)
++{
++	struct cmd_priv 		*pcmdpriv = &padapter->cmdpriv;
++	struct cmd_obj*			ph2c;
++	struct set_assocsta_parm	*psetassocsta_para;
++	struct set_stakey_rsp		*psetassocsta_rsp = NULL;
++
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	psetassocsta_para = (struct set_assocsta_parm*)rtw_zmalloc(sizeof(struct set_assocsta_parm));
++	if(psetassocsta_para==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		res=_FAIL;
++		goto exit;
++	}
++
++	psetassocsta_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_assocsta_rsp));
++	if(psetassocsta_rsp==NULL){
++		rtw_mfree((u8 *) ph2c, sizeof(struct	cmd_obj));
++		rtw_mfree((u8 *) psetassocsta_para, sizeof(struct set_assocsta_parm));
++		return _FAIL;
++	}
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
++	ph2c->rsp = (u8 *) psetassocsta_rsp;
++	ph2c->rspsz = sizeof(struct set_assocsta_rsp);
++
++	_rtw_memcpy(psetassocsta_para->addr, mac_addr,ETH_ALEN);
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++ }
++
++u8 rtw_addbareq_cmd(_adapter*padapter, u8 tid, u8 *addr)
++{
++	struct cmd_priv		*pcmdpriv = &padapter->cmdpriv;
++	struct cmd_obj*		ph2c;
++	struct addBaReq_parm	*paddbareq_parm;
++
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	paddbareq_parm = (struct addBaReq_parm*)rtw_zmalloc(sizeof(struct addBaReq_parm));
++	if(paddbareq_parm==NULL){
++		rtw_mfree((unsigned char *)ph2c, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	paddbareq_parm->tid = tid;
++	_rtw_memcpy(paddbareq_parm->addr, addr, ETH_ALEN);
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq));
++
++	//DBG_871X("rtw_addbareq_cmd, tid=%d\n", tid);
++
++	//rtw_enqueue_cmd(pcmdpriv, ph2c);
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++//add for CONFIG_IEEE80211W, none 11w can use it
++u8 rtw_reset_securitypriv_cmd(_adapter*padapter)
++{
++	struct cmd_obj*		ph2c;
++	struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if(pdrvextra_cmd_parm==NULL){
++		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV;
++	pdrvextra_cmd_parm->type_size = 0;
++	pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++
++	//rtw_enqueue_cmd(pcmdpriv, ph2c);
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++u8 rtw_free_assoc_resources_cmd(_adapter*padapter)
++{
++	struct cmd_obj*		ph2c;
++	struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if(pdrvextra_cmd_parm==NULL){
++		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES;
++	pdrvextra_cmd_parm->type_size = 0;
++	pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++
++	//rtw_enqueue_cmd(pcmdpriv, ph2c);
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++
++u8 rtw_dynamic_chk_wk_cmd(_adapter*padapter)
++{
++	struct cmd_obj*		ph2c;
++	struct drvextra_cmd_parm  *pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv=&padapter->cmdpriv;
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
++		goto exit;
++
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if (padapter->adapter_type != PRIMARY_ADAPTER && padapter->pbuddy_adapter)
++		pcmdpriv = &(padapter->pbuddy_adapter->cmdpriv);
++#endif
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if(pdrvextra_cmd_parm==NULL){
++		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID;
++	pdrvextra_cmd_parm->type_size = 0;
++	pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++
++	//rtw_enqueue_cmd(pcmdpriv, ph2c);
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++u8 rtw_set_ch_cmd(_adapter*padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue)
++{
++	struct cmd_obj *pcmdobj;
++	struct set_ch_parm *set_ch_parm;
++	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
++
++	u8 res=_SUCCESS;
++
++_func_enter_;
++
++	DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
++		FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset);
++
++	/* check input parameter */
++
++	/* prepare cmd parameter */
++	set_ch_parm = (struct set_ch_parm *)rtw_zmalloc(sizeof(*set_ch_parm));
++	if (set_ch_parm == NULL) {
++		res= _FAIL;
++		goto exit;
++	}
++	set_ch_parm->ch = ch;
++	set_ch_parm->bw = bw;
++	set_ch_parm->ch_offset = ch_offset;
++
++	if (enqueue) {
++		/* need enqueue, prepare cmd_obj and enqueue */
++		pcmdobj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++		if(pcmdobj == NULL){
++			rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm));
++			res=_FAIL;
++			goto exit;
++		}
++
++		init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel));
++		res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
++	} else {
++		/* no need to enqueue, do the cmd hdl directly and free cmd parameter */
++		if( H2C_SUCCESS !=set_ch_hdl(padapter, (u8 *)set_ch_parm) )
++			res = _FAIL;
++
++		rtw_mfree((u8 *)set_ch_parm, sizeof(*set_ch_parm));
++	}
++
++	/* do something based on res... */
++
++exit:
++
++	DBG_871X(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res);
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_set_chplan_cmd(_adapter*padapter, u8 chplan, u8 enqueue)
++{
++	struct	cmd_obj*	pcmdobj;
++	struct	SetChannelPlan_param *setChannelPlan_param;
++	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
++
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n"));
++
++	//check input parameter
++	if(!rtw_is_channel_plan_valid(chplan)) {
++		res = _FAIL;
++		goto exit;
++	}
++
++	//prepare cmd parameter
++	setChannelPlan_param = (struct	SetChannelPlan_param *)rtw_zmalloc(sizeof(struct SetChannelPlan_param));
++	if(setChannelPlan_param == NULL) {
++		res= _FAIL;
++		goto exit;
++	}
++	setChannelPlan_param->channel_plan=chplan;
++
++	if(enqueue)
++	{
++		//need enqueue, prepare cmd_obj and enqueue
++		pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++		if(pcmdobj == NULL){
++			rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param));
++			res=_FAIL;
++			goto exit;
++		}
++
++		init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan));
++		res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
++	}
++	else
++	{
++		//no need to enqueue, do the cmd hdl directly and free cmd parameter
++		if( H2C_SUCCESS !=set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param) )
++			res = _FAIL;
++
++		rtw_mfree((u8 *)setChannelPlan_param, sizeof(struct SetChannelPlan_param));
++	}
++
++	//do something based on res...
++	if(res == _SUCCESS)
++		padapter->mlmepriv.ChannelPlan = chplan;
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_led_blink_cmd(_adapter*padapter, PLED_871x pLed)
++{
++	struct	cmd_obj*	pcmdobj;
++	struct	LedBlink_param *ledBlink_param;
++	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
++
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_led_blink_cmd\n"));
++
++	pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++	if(pcmdobj == NULL){
++		res=_FAIL;
++		goto exit;
++	}
++
++	ledBlink_param = (struct	LedBlink_param *)rtw_zmalloc(sizeof(struct	LedBlink_param));
++	if(ledBlink_param == NULL) {
++		rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	ledBlink_param->pLed=pLed;
++
++	init_h2fwcmd_w_parm_no_rsp(pcmdobj, ledBlink_param, GEN_CMD_CODE(_LedBlink));
++	res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_set_csa_cmd(_adapter*padapter, u8 new_ch_no)
++{
++	struct	cmd_obj*	pcmdobj;
++	struct	SetChannelSwitch_param*setChannelSwitch_param;
++	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
++
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n"));
++
++	pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++	if(pcmdobj == NULL){
++		res=_FAIL;
++		goto exit;
++	}
++
++	setChannelSwitch_param = (struct SetChannelSwitch_param *)rtw_zmalloc(sizeof(struct	SetChannelSwitch_param));
++	if(setChannelSwitch_param == NULL) {
++		rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	setChannelSwitch_param->new_ch_no=new_ch_no;
++
++	init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch));
++	res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_tdls_cmd(_adapter *padapter, u8 *addr, u8 option)
++{
++	struct	cmd_obj*	pcmdobj;
++	struct	TDLSoption_param	*TDLSoption;
++	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct	cmd_priv   *pcmdpriv = &padapter->cmdpriv;
++
++	u8	res=_SUCCESS;
++
++_func_enter_;
++
++#ifdef CONFIG_TDLS
++
++	RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_tdls_cmd\n"));
++
++	pcmdobj = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++	if(pcmdobj == NULL){
++		res=_FAIL;
++		goto exit;
++	}
++
++	TDLSoption= (struct TDLSoption_param *)rtw_zmalloc(sizeof(struct TDLSoption_param));
++	if(TDLSoption == NULL) {
++		rtw_mfree((u8 *)pcmdobj, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	_rtw_spinlock(&(padapter->tdlsinfo.cmd_lock));
++	_rtw_memcpy(TDLSoption->addr, addr, 6);
++	TDLSoption->option = option;
++	_rtw_spinunlock(&(padapter->tdlsinfo.cmd_lock));
++	init_h2fwcmd_w_parm_no_rsp(pcmdobj, TDLSoption, GEN_CMD_CODE(_TDLS));
++	res = rtw_enqueue_cmd(pcmdpriv, pcmdobj);
++
++#endif	//CONFIG_TDLS
++
++exit:
++
++
++_func_exit_;
++
++	return res;
++}
++
++static void traffic_status_watchdog(_adapter *padapter)
++{
++#ifdef CONFIG_LPS
++	u8	bEnterPS;
++#endif
++	u16	BusyThreshold = 100;
++	u8	bBusyTraffic = _FALSE, bTxBusyTraffic = _FALSE, bRxBusyTraffic = _FALSE;
++	u8	bHigherBusyTraffic = _FALSE, bHigherBusyRxTraffic = _FALSE, bHigherBusyTxTraffic = _FALSE;
++	struct mlme_priv		*pmlmepriv = &(padapter->mlmepriv);
++#ifdef CONFIG_TDLS
++	struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
++#endif //CONFIG_TDLS
++
++	RT_LINK_DETECT_T * link_detect = &pmlmepriv->LinkDetectInfo;
++
++	//
++	// Determine if our traffic is busy now
++	//
++	if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
++		/*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
++	{
++
++		// if we raise bBusyTraffic in last watchdog, using lower threshold.
++		if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
++			BusyThreshold = 75;
++		if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold ||
++			pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold )
++		{
++			bBusyTraffic = _TRUE;
++
++			if(pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold)
++				bRxBusyTraffic = _TRUE;
++
++			if(pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold)
++				bTxBusyTraffic = _TRUE;
++		}
++
++		// Higher Tx/Rx data.
++		if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 ||
++			pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000 )
++		{
++			bHigherBusyTraffic = _TRUE;
++
++			// Extremely high Rx data.
++			if(pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 5000)
++				bHigherBusyRxTraffic = _TRUE;
++
++			// Extremely high Tx data.
++			if(pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 5000)
++				bHigherBusyTxTraffic = _TRUE;
++		}
++
++#ifdef CONFIG_TRAFFIC_PROTECT
++#define TX_ACTIVE_TH 2
++#define RX_ACTIVE_TH 1
++#define TRAFFIC_PROTECT_PERIOD_MS 4500
++
++	if (link_detect->NumTxOkInPeriod > TX_ACTIVE_TH
++		|| link_detect->NumRxUnicastOkInPeriod > RX_ACTIVE_TH) {
++
++		LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT" acqiure wake_lock for %u ms(tx:%d,rx_unicast:%d)\n",
++			FUNC_ADPT_ARG(padapter),
++			TRAFFIC_PROTECT_PERIOD_MS,
++			link_detect->NumTxOkInPeriod,
++			link_detect->NumRxUnicastOkInPeriod);
++
++		rtw_lock_suspend_timeout(TRAFFIC_PROTECT_PERIOD_MS);
++	}
++#endif
++
++#ifdef CONFIG_TDLS
++#ifdef CONFIG_TDLS_AUTOSETUP
++		if( ( ptdlsinfo->watchdog_count % TDLS_WATCHDOG_PERIOD ) == 0 )	//TDLS_WATCHDOG_PERIOD * 2sec, periodically sending
++			issue_tdls_dis_req( padapter, NULL );
++		ptdlsinfo->watchdog_count++;
++#endif //CONFIG_TDLS_AUTOSETUP
++#endif //CONFIG_TDLS
++
++#ifdef CONFIG_LPS
++		// check traffic for  powersaving.
++		if( ((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8 ) ||
++			(pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) )
++		{
++			//DBG_871X("Tx = %d, Rx = %d \n",pmlmepriv->LinkDetectInfo.NumTxOkInPeriod,pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod);
++			bEnterPS= _FALSE;
++		}
++		else
++		{
++			bEnterPS= _TRUE;
++		}
++
++		// LeisurePS only work in infra mode.
++		if(bEnterPS)
++		{
++			LPS_Enter(padapter);
++		}
++		else
++		{
++			LPS_Leave(padapter);
++		}
++#endif
++	}
++	else
++	{
++#ifdef CONFIG_LPS
++		LPS_Leave(padapter);
++#endif
++	}
++
++	pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0;
++	pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0;
++	pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0;
++	pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic;
++	pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic;
++	pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic;
++	pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic;
++	pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic;
++	pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic;
++
++}
++
++void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz);
++void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz)
++{
++	struct mlme_priv *pmlmepriv;
++
++	if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
++		return;
++
++	if((void*)padapter != (void*)pbuf && padapter->pbuddy_adapter == NULL)
++		return;
++
++	padapter = (_adapter *)pbuf;
++
++	if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
++		return;
++
++	pmlmepriv = &(padapter->mlmepriv);
++
++#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++#ifdef CONFIG_AP_MODE
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++	{
++		expire_timeout_chk(padapter);
++	}
++#endif
++#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++
++	#ifdef DBG_CONFIG_ERROR_DETECT
++	rtw_hal_sreset_xmit_status_check(padapter);
++	#endif
++
++	//if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY)==_FALSE)
++	{
++		linked_status_chk(padapter);
++		traffic_status_watchdog(padapter);
++	}
++
++	rtw_hal_dm_watchdog(padapter);
++
++	//check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
++
++}
++
++#ifdef CONFIG_LPS
++
++void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type);
++void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type)
++{
++	struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	u8	mstatus;
++
++_func_enter_;
++
++	if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
++		|| (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
++	{
++		return;
++	}
++
++	switch(lps_ctrl_type)
++	{
++		case LPS_CTRL_SCAN:
++			//DBG_871X("LPS_CTRL_SCAN \n");
++			LeaveAllPowerSaveMode(padapter);
++			break;
++		case LPS_CTRL_JOINBSS:
++			//DBG_871X("LPS_CTRL_JOINBSS \n");
++			LPS_Leave(padapter);
++			break;
++		case LPS_CTRL_CONNECT:
++			//DBG_871X("LPS_CTRL_CONNECT \n");
++			mstatus = 1;
++			// Reset LPS Setting
++			padapter->pwrctrlpriv.LpsIdleCount = 0;
++			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
++			break;
++		case LPS_CTRL_DISCONNECT:
++			//DBG_871X("LPS_CTRL_DISCONNECT \n");
++			mstatus = 0;
++			LPS_Leave(padapter);
++			rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
++			break;
++		case LPS_CTRL_SPECIAL_PACKET:
++			//DBG_871X("LPS_CTRL_SPECIAL_PACKET \n");
++			pwrpriv->DelayLPSLastTimeStamp = rtw_get_current_time();
++			LPS_Leave(padapter);
++			break;
++
++		default:
++			break;
++	}
++
++_func_exit_;
++}
++
++u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue)
++{
++	struct cmd_obj	*ph2c;
++	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
++	//struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
++	u8	res = _SUCCESS;
++
++_func_enter_;
++
++	//if(!pwrctrlpriv->bLeisurePs)
++	//	return res;
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if (padapter->iface_type != IFACE_PORT0)
++		return res;
++#endif
++
++	if(enqueue)
++	{
++		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++		if(ph2c==NULL){
++			res= _FAIL;
++			goto exit;
++		}
++
++		pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++		if(pdrvextra_cmd_parm==NULL){
++			rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++			res= _FAIL;
++			goto exit;
++		}
++
++		pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID;
++		pdrvextra_cmd_parm->type_size = lps_ctrl_type;
++		pdrvextra_cmd_parm->pbuf = NULL;
++
++		init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++	}
++	else
++	{
++		lps_ctrl_wk_hdl(padapter, lps_ctrl_type);
++	}
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++#endif
++#ifdef CONFIG_ANTENNA_DIVERSITY
++
++void antenna_select_wk_hdl(_adapter *padapter, u8 antenna)
++{
++	rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna));
++}
++
++u8 rtw_antenna_select_cmd(_adapter*padapter, u8 antenna,u8 enqueue)
++{
++	struct cmd_obj		*ph2c;
++	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
++	u8 	bSupportAntDiv = _FALSE;
++	u8	res = _SUCCESS;
++
++_func_enter_;
++	rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
++	if(_FALSE == bSupportAntDiv )	return res;
++
++	if(_TRUE == enqueue)
++	{
++		ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++		if(ph2c==NULL){
++			res= _FAIL;
++			goto exit;
++		}
++
++		pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++		if(pdrvextra_cmd_parm==NULL){
++			rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++			res= _FAIL;
++			goto exit;
++		}
++
++		pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID;
++		pdrvextra_cmd_parm->type_size = antenna;
++		pdrvextra_cmd_parm->pbuf = NULL;
++		init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++		res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++	}
++	else{
++		antenna_select_wk_hdl(padapter,antenna );
++	}
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++#endif
++
++void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz);
++void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz)
++{
++	 rtw_ps_processor(padapter);
++}
++
++//add for CONFIG_IEEE80211W, none 11w can use it
++void reset_securitypriv_hdl(_adapter *padapter)
++{
++	 rtw_reset_securitypriv(padapter);
++}
++
++void free_assoc_resources_hdl(_adapter *padapter)
++{
++	 rtw_free_assoc_resources(padapter, 1);
++}
++
++#ifdef CONFIG_P2P
++u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType )
++{
++	struct cmd_obj	*ph2c;
++	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
++	struct wifidirect_info	*pwdinfo= &(padapter->wdinfo);
++	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
++	u8	res = _SUCCESS;
++
++_func_enter_;
++
++	if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
++	{
++		return res;
++	}
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if(pdrvextra_cmd_parm==NULL){
++		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = P2P_PROTO_WK_CID;
++	pdrvextra_cmd_parm->type_size = intCmdType;	//	As the command tppe.
++	pdrvextra_cmd_parm->pbuf = NULL;		//	Must be NULL here
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++#endif //CONFIG_P2P
++
++u8 rtw_ps_cmd(_adapter*padapter)
++{
++	struct cmd_obj		*ppscmd;
++	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
++
++	u8	res = _SUCCESS;
++_func_enter_;
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if (padapter->adapter_type != PRIMARY_ADAPTER)
++		goto exit;
++#endif
++
++	ppscmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ppscmd==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if(pdrvextra_cmd_parm==NULL){
++		rtw_mfree((unsigned char *)ppscmd, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID;
++	pdrvextra_cmd_parm->pbuf = NULL;
++	init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++	res = rtw_enqueue_cmd(pcmdpriv, ppscmd);
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++#ifdef CONFIG_AP_MODE
++
++static void rtw_chk_hi_queue_hdl(_adapter *padapter)
++{
++	int cnt=0;
++	struct sta_info *psta_bmc;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++
++	psta_bmc = rtw_get_bcmc_stainfo(padapter);
++	if(!psta_bmc)
++		return;
++
++
++	if(psta_bmc->sleepq_len==0)
++	{
++		while((rtw_read32(padapter, 0x414)&0x00ffff00)!=0)
++		{
++			rtw_msleep_os(100);
++
++			cnt++;
++
++			if(cnt>10)
++				break;
++		}
++
++		if(cnt<=10)
++		{
++			pstapriv->tim_bitmap &= ~BIT(0);
++			pstapriv->sta_dz_bitmap &= ~BIT(0);
++
++			update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
++		}
++	}
++
++}
++
++u8 rtw_chk_hi_queue_cmd(_adapter*padapter)
++{
++	struct cmd_obj	*ph2c;
++	struct drvextra_cmd_parm	*pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
++	u8	res = _SUCCESS;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if(ph2c==NULL){
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if(pdrvextra_cmd_parm==NULL){
++		rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID;
++	pdrvextra_cmd_parm->type_size = 0;
++	pdrvextra_cmd_parm->pbuf = NULL;
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++	return res;
++
++}
++#endif
++
++u8 rtw_c2h_wk_cmd(PADAPTER padapter, u8 *c2h_evt)
++{
++	struct cmd_obj *ph2c;
++	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
++	struct cmd_priv	*pcmdpriv = &padapter->cmdpriv;
++	u8	res = _SUCCESS;
++
++	ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
++	if (ph2c == NULL) {
++		res = _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
++	if (pdrvextra_cmd_parm == NULL) {
++		rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
++		res = _FAIL;
++		goto exit;
++	}
++
++	pdrvextra_cmd_parm->ec_id = C2H_WK_CID;
++	pdrvextra_cmd_parm->type_size = c2h_evt?16:0;
++	pdrvextra_cmd_parm->pbuf = c2h_evt;
++
++	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
++
++	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
++
++exit:
++
++	return res;
++}
++
++s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter)
++{
++	s32 ret = _FAIL;
++	u8 buf[16];
++
++	if (!c2h_evt) {
++		/* No c2h event in cmd_obj, read c2h event before handling*/
++		if (c2h_evt_read(adapter, buf) == _SUCCESS) {
++			c2h_evt = (struct c2h_evt_hdr *)buf;
++
++			if (filter && filter(c2h_evt->id) == _FALSE)
++				goto exit;
++
++			ret = rtw_hal_c2h_handler(adapter, c2h_evt);
++		}
++	} else {
++
++		if (filter && filter(c2h_evt->id) == _FALSE)
++			goto exit;
++
++		ret = rtw_hal_c2h_handler(adapter, c2h_evt);
++	}
++exit:
++	return ret;
++}
++
++#ifdef CONFIG_C2H_WK
++static void c2h_wk_callback(_workitem *work)
++{
++	struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk);
++	_adapter *adapter = container_of(evtpriv, _adapter, evtpriv);
++	struct c2h_evt_hdr *c2h_evt;
++	c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
++
++	evtpriv->c2h_wk_alive = _TRUE;
++
++	while (!rtw_cbuf_empty(evtpriv->c2h_queue)) {
++		if ((c2h_evt = (struct c2h_evt_hdr *)rtw_cbuf_pop(evtpriv->c2h_queue)) != NULL) {
++			/* This C2H event is read, clear it */
++			c2h_evt_clear(adapter);
++		} else if ((c2h_evt = (struct c2h_evt_hdr *)rtw_malloc(16)) != NULL) {
++			/* This C2H event is not read, read & clear now */
++			if (c2h_evt_read(adapter, (u8*)c2h_evt) != _SUCCESS)
++				continue;
++		}
++
++		/* Special pointer to trigger c2h_evt_clear only */
++		if ((void *)c2h_evt == (void *)evtpriv)
++			continue;
++
++		if (!c2h_evt_exist(c2h_evt)) {
++			rtw_mfree((u8*)c2h_evt, 16);
++			continue;
++		}
++
++		if (ccx_id_filter(c2h_evt->id) == _TRUE) {
++			/* Handle CCX report here */
++			rtw_hal_c2h_handler(adapter, c2h_evt);
++			rtw_mfree((u8*)c2h_evt, 16);
++		} else {
++			/* Enqueue into cmd_thread for others */
++			rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
++		}
++	}
++
++	evtpriv->c2h_wk_alive = _FALSE;
++}
++#endif
++
++u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf)
++{
++	struct drvextra_cmd_parm *pdrvextra_cmd;
++
++	if(!pbuf)
++		return H2C_PARAMETERS_ERROR;
++
++	pdrvextra_cmd = (struct drvextra_cmd_parm*)pbuf;
++
++	switch(pdrvextra_cmd->ec_id)
++	{
++		case DYNAMIC_CHK_WK_CID:
++			dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
++			break;
++		case POWER_SAVING_CTRL_WK_CID:
++			power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
++			break;
++#ifdef CONFIG_LPS
++		case LPS_CTRL_WK_CID:
++			lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size);
++			break;
++#endif
++#ifdef CONFIG_ANTENNA_DIVERSITY
++		case ANT_SELECT_WK_CID:
++			antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size);
++			break;
++#endif
++#ifdef CONFIG_P2P_PS
++		case P2P_PS_WK_CID:
++			p2p_ps_wk_hdl(padapter, pdrvextra_cmd->type_size);
++			break;
++#endif // CONFIG_P2P_PS
++		case P2P_PROTO_WK_CID:
++			//	Commented by Albert 2011/07/01
++			//	I used the type_size as the type command
++			p2p_protocol_wk_hdl( padapter, pdrvextra_cmd->type_size );
++			break;
++#ifdef CONFIG_AP_MODE
++		case CHECK_HIQ_WK_CID:
++			rtw_chk_hi_queue_hdl(padapter);
++			break;
++#endif //CONFIG_AP_MODE
++#ifdef CONFIG_INTEL_WIDI
++		case INTEl_WIDI_WK_CID:
++			intel_widi_wk_hdl(padapter, pdrvextra_cmd->type_size, pdrvextra_cmd->pbuf);
++			break;
++#endif //CONFIG_INTEL_WIDI
++		//add for CONFIG_IEEE80211W, none 11w can use it
++		case RESET_SECURITYPRIV:
++			reset_securitypriv_hdl(padapter);
++			break;
++		case FREE_ASSOC_RESOURCES:
++			free_assoc_resources_hdl(padapter);
++			break;
++		case C2H_WK_CID:
++			c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL);
++			break;
++
++		default:
++			break;
++	}
++
++
++	if(pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size>0)
++	{
++		rtw_mfree(pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
++	}
++
++
++	return H2C_SUCCESS;
++
++}
++
++void rtw_survey_cmd_callback(_adapter*	padapter ,  struct cmd_obj *pcmd)
++{
++	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	if(pcmd->res == H2C_DROPPED)
++	{
++		//TODO: cancel timer and do timeout handler directly...
++		//need to make timeout handlerOS independent
++		_set_timer(&pmlmepriv->scan_to_timer, 1);
++	}
++	else if (pcmd->res != H2C_SUCCESS) {
++		_set_timer(&pmlmepriv->scan_to_timer, 1);
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
++	}
++
++	// free cmd
++	rtw_free_cmd_obj(pcmd);
++
++_func_exit_;
++}
++void rtw_disassoc_cmd_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
++{
++	_irqL	irqL;
++	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	if (pcmd->res != H2C_SUCCESS)
++	{
++		_enter_critical_bh(&pmlmepriv->lock, &irqL);
++		set_fwstate(pmlmepriv, _FW_LINKED);
++		_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ***Error: disconnect_cmd_callback Fail ***\n."));
++
++		goto exit;
++	}
++#ifdef CONFIG_BR_EXT
++	else //clear bridge database
++		nat25_db_cleanup(padapter);
++#endif //CONFIG_BR_EXT
++
++	// free cmd
++	rtw_free_cmd_obj(pcmd);
++
++exit:
++
++_func_exit_;
++}
++
++
++void rtw_joinbss_cmd_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
++{
++	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	if(pcmd->res == H2C_DROPPED)
++	{
++		//TODO: cancel timer and do timeout handler directly...
++		//need to make timeout handlerOS independent
++		_set_timer(&pmlmepriv->assoc_timer, 1);
++	}
++	else if(pcmd->res != H2C_SUCCESS)
++	{
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("********Error:rtw_select_and_join_from_scanned_queue Wait Sema  Fail ************\n"));
++		_set_timer(&pmlmepriv->assoc_timer, 1);
++	}
++
++	rtw_free_cmd_obj(pcmd);
++
++_func_exit_;
++}
++
++void rtw_createbss_cmd_callback(_adapter *padapter, struct cmd_obj *pcmd)
++{
++	_irqL irqL;
++	u8 timer_cancelled;
++	struct sta_info *psta = NULL;
++	struct wlan_network *pwlan = NULL;
++	struct 	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)pcmd->parmbuf;
++	struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
++
++_func_enter_;
++
++	if((pcmd->res != H2C_SUCCESS))
++	{
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n ********Error: rtw_createbss_cmd_callback  Fail ************\n\n."));
++		_set_timer(&pmlmepriv->assoc_timer, 1 );
++	}
++
++	_cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
++
++#ifdef CONFIG_FW_MLMLE
++       //endian_convert
++	pnetwork->Length = le32_to_cpu(pnetwork->Length);
++	pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
++	pnetwork->Privacy =le32_to_cpu(pnetwork->Privacy);
++	pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
++	pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse);
++	pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow);
++	//pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
++	pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig);
++	pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
++	pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
++	pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
++	pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
++	pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length);
++	pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode);
++	pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
++#endif
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) )
++	{
++		psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress);
++		if(!psta)
++		{
++		psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress);
++		if (psta == NULL)
++		{
++			RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nCan't alloc sta_info when createbss_cmd_callback\n"));
++			goto createbss_cmd_fail ;
++		}
++		}
++
++		rtw_indicate_connect( padapter);
++	}
++	else
++	{
++		_irqL	irqL;
++
++		pwlan = _rtw_alloc_network(pmlmepriv);
++		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		if ( pwlan == NULL)
++		{
++			pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue);
++			if( pwlan == NULL)
++			{
++				RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\n Error:  can't get pwlan in rtw_joinbss_event_callback \n"));
++				_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++				goto createbss_cmd_fail;
++			}
++			pwlan->last_scanned = rtw_get_current_time();
++		}
++		else
++		{
++			rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
++		}
++
++		pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
++		_rtw_memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
++		//pwlan->fixed = _TRUE;
++
++		//rtw_list_insert_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue);
++
++		// copy pdev_network information to 	pmlmepriv->cur_network
++		_rtw_memcpy(&tgt_network->network, pnetwork, (get_WLAN_BSSID_EX_sz(pnetwork)));
++
++		// reset DSConfig
++		//tgt_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pnetwork->Configuration.DSConfig);
++
++		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++
++#if 0
++		if((pmlmepriv->fw_state) & WIFI_AP_STATE)
++		{
++			psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress);
++
++			if (psta == NULL) { // for AP Mode & Adhoc Master Mode
++				RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nCan't alloc sta_info when createbss_cmd_callback\n"));
++				goto createbss_cmd_fail ;
++			}
++
++			rtw_indicate_connect( padapter);
++		}
++		else {
++
++			//rtw_indicate_disconnect(dev);
++		}
++#endif
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		// we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback)
++
++	}
++
++createbss_cmd_fail:
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++	rtw_free_cmd_obj(pcmd);
++
++_func_exit_;
++
++}
++
++
++
++void rtw_setstaKey_cmdrsp_callback(_adapter*	padapter ,  struct cmd_obj *pcmd)
++{
++
++	struct sta_priv * pstapriv = &padapter->stapriv;
++	struct set_stakey_rsp* psetstakey_rsp = (struct set_stakey_rsp*) (pcmd->rsp);
++	struct sta_info*	psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr);
++
++_func_enter_;
++
++	if(psta==NULL)
++	{
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info \n\n"));
++		goto exit;
++	}
++
++	//psta->aid = psta->mac_id = psetstakey_rsp->keyid; //CAM_ID(CAM_ENTRY)
++
++exit:
++
++	rtw_free_cmd_obj(pcmd);
++
++_func_exit_;
++
++}
++void rtw_setassocsta_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
++{
++	_irqL	irqL;
++	struct sta_priv * pstapriv = &padapter->stapriv;
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	struct set_assocsta_parm* passocsta_parm = (struct set_assocsta_parm*)(pcmd->parmbuf);
++	struct set_assocsta_rsp* passocsta_rsp = (struct set_assocsta_rsp*) (pcmd->rsp);
++	struct sta_info*	psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr);
++
++_func_enter_;
++
++	if(psta==NULL)
++	{
++		RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info \n\n"));
++		goto exit;
++	}
++
++	psta->aid = psta->mac_id = passocsta_rsp->cam_id;
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE))
++		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++
++       set_fwstate(pmlmepriv, _FW_LINKED);
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++exit:
++	rtw_free_cmd_obj(pcmd);
++
++_func_exit_;
++}
++
++void rtw_getrttbl_cmd_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd);
++void rtw_getrttbl_cmd_cmdrsp_callback(_adapter*	padapter,  struct cmd_obj *pcmd)
++{
++_func_enter_;
++
++	rtw_free_cmd_obj(pcmd);
++#ifdef CONFIG_MP_INCLUDED
++	padapter->mppriv.workparam.bcompleted=_TRUE;
++#endif
++
++_func_exit_;
++
++}
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_debug.c
+@@ -0,0 +1,1336 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_DEBUG_C_
++
++
++#include <rtw_debug.h>
++#include <../hal/dm.h>
++
++//#ifdef CONFIG_DEBUG_RTL871X
++
++	u32 GlobalDebugLevel = _drv_err_;
++
++	u64 GlobalDebugComponents = \
++			_module_rtl871x_xmit_c_ |
++			_module_xmit_osdep_c_ |
++			_module_rtl871x_recv_c_ |
++			_module_recv_osdep_c_ |
++			_module_rtl871x_mlme_c_ |
++			_module_mlme_osdep_c_ |
++			_module_rtl871x_sta_mgt_c_ |
++			_module_rtl871x_cmd_c_ |
++			_module_cmd_osdep_c_ |
++			_module_rtl871x_io_c_ |
++			_module_io_osdep_c_ |
++			_module_os_intfs_c_|
++			_module_rtl871x_security_c_|
++			_module_rtl871x_eeprom_c_|
++			_module_hal_init_c_|
++			_module_hci_hal_init_c_|
++			_module_rtl871x_ioctl_c_|
++			_module_rtl871x_ioctl_set_c_|
++			_module_rtl871x_ioctl_query_c_|
++			_module_rtl871x_pwrctrl_c_|
++			_module_hci_intfs_c_|
++			_module_hci_ops_c_|
++			_module_hci_ops_os_c_|
++			_module_rtl871x_ioctl_os_c|
++			_module_rtl8712_cmd_c_|
++			_module_hal_xmit_c_|
++			_module_rtl8712_recv_c_ |
++			_module_mp_ |
++			_module_efuse_;
++
++//#endif
++
++#ifdef CONFIG_PROC_DEBUG
++#include <rtw_version.h>
++
++int proc_get_drv_version(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_log_level(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len,
++		"log_level:%d\n",
++		GlobalDebugLevel
++		);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_log_level(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	char tmp[32];
++	u32 is_signal_dbg;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%d ", &is_signal_dbg);
++
++		if( is_signal_dbg >= 0 && is_signal_dbg < 10 )
++		{
++			GlobalDebugLevel= is_signal_dbg;
++			printk("%d\n", GlobalDebugLevel);
++		}
++	}
++
++	return count;
++
++}
++
++#ifdef DBG_MEM_ALLOC
++int proc_get_mstat(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	int len = 0;
++
++	len += _rtw_mstat_dump(page+len, count-len);
++	*eof = 1;
++
++	return len;
++}
++#endif /* DBG_MEM_ALLOC */
++
++int proc_get_write_reg(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	*eof = 1;
++	return 0;
++}
++
++int proc_set_write_reg(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	char tmp[32];
++	u32 addr, val, len;
++
++	if (count < 3)
++	{
++		DBG_871X("argument size is less than 3\n");
++		return -EFAULT;
++	}
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
++
++		if (num !=  3) {
++			DBG_871X("invalid write_reg parameter!\n");
++			return count;
++		}
++
++		switch(len)
++		{
++			case 1:
++				rtw_write8(padapter, addr, (u8)val);
++				break;
++			case 2:
++				rtw_write16(padapter, addr, (u16)val);
++				break;
++			case 4:
++				rtw_write32(padapter, addr, val);
++				break;
++			default:
++				DBG_871X("error write length=%d", len);
++				break;
++		}
++
++	}
++
++	return count;
++
++}
++
++static u32 proc_get_read_addr=0xeeeeeeee;
++static u32 proc_get_read_len=0x4;
++
++int proc_get_read_reg(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++
++	int len = 0;
++
++	if(proc_get_read_addr==0xeeeeeeee)
++	{
++		*eof = 1;
++		return len;
++	}
++
++	switch(proc_get_read_len)
++	{
++		case 1:
++			len += snprintf(page + len, count - len, "rtw_read8(0x%x)=0x%x\n", proc_get_read_addr, rtw_read8(padapter, proc_get_read_addr));
++			break;
++		case 2:
++			len += snprintf(page + len, count - len, "rtw_read16(0x%x)=0x%x\n", proc_get_read_addr, rtw_read16(padapter, proc_get_read_addr));
++			break;
++		case 4:
++			len += snprintf(page + len, count - len, "rtw_read32(0x%x)=0x%x\n", proc_get_read_addr, rtw_read32(padapter, proc_get_read_addr));
++			break;
++		default:
++			len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
++			break;
++	}
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_set_read_reg(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	char tmp[16];
++	u32 addr, len;
++
++	if (count < 2)
++	{
++		DBG_871X("argument size is less than 2\n");
++		return -EFAULT;
++	}
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%x %x", &addr, &len);
++
++		if (num !=  2) {
++			DBG_871X("invalid read_reg parameter!\n");
++			return count;
++		}
++
++		proc_get_read_addr = addr;
++
++		proc_get_read_len = len;
++	}
++
++	return count;
++
++}
++
++int proc_get_fwstate(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "fwstate=0x%x\n", get_fwstate(pmlmepriv));
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_sec_info(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct security_priv *psecuritypriv = &padapter->securitypriv;
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
++						psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
++						psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_mlmext_state(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "pmlmeinfo->state=0x%x\n", pmlmeinfo->state);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_qos_option(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "qos_option=%d\n", pmlmepriv->qospriv.qos_option);
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_get_ht_option(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "ht_option=%d\n", pmlmepriv->htpriv.ht_option);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_rf_info(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "cur_ch=%d, cur_bw=%d, cur_ch_offet=%d\n"
++		"oper_ch=%d, oper_bw=%d, oper_ch_offet=%d\n",
++		pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset,
++		rtw_get_oper_ch(padapter), rtw_get_oper_bw(padapter), rtw_get_oper_choffset(padapter));
++	*eof = 1;
++
++	return len;
++}
++
++int proc_get_ap_info(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct sta_info *psta;
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct wlan_network *cur_network = &(pmlmepriv->cur_network);
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	int len = 0;
++
++	psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
++	if(psta)
++	{
++		int i;
++		struct recv_reorder_ctrl *preorder_ctrl;
++
++		len += snprintf(page + len, count - len, "SSID=%s\n", cur_network->network.Ssid.Ssid);
++		len += snprintf(page + len, count - len, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
++		len += snprintf(page + len, count - len, "cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
++		len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
++		len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
++		len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
++		len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
++		len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
++		len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
++
++		for(i=0;i<16;i++)
++		{
++			preorder_ctrl = &psta->recvreorder_ctrl[i];
++			if(preorder_ctrl->enable)
++			{
++				len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", i, preorder_ctrl->indicate_seq);
++			}
++		}
++
++	}
++	else
++	{
++		len += snprintf(page + len, count - len, "can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
++	}
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_get_adapter_state(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n",
++						padapter->bSurpriseRemoved, padapter->bDriverStopped);
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_get_trx_info(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	int i;
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
++	struct recv_priv  *precvpriv = &padapter->recvpriv;
++	struct dvobj_priv	*pdvobj = adapter_to_dvobj(padapter);
++        struct hw_xmit *phwxmit;
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
++				", free_ext_xmitbuf_cnt=%d, free_xframe_ext_cnt=%d"
++				", free_recvframe_cnt=%d\n",
++				pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
++				pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
++				precvpriv->free_recvframe_cnt);
++#ifdef CONFIG_USB_HCI
++	len += snprintf(page + len, count - len, "rx_urb_pending_cnt=%d\n", precvpriv->rx_pending_cnt);
++#endif
++
++	len += snprintf(page + len, count - len, "recvbuf_skb_alloc_fail_cnt=%d\n", precvpriv->recvbuf_skb_alloc_fail_cnt);
++	len += snprintf(page + len, count - len, "recvbuf_null_cnt=%d\n", precvpriv->recvbuf_null_cnt);
++	len += snprintf(page + len, count - len, "read_port_complete_EINPROGRESS_cnt=%d\n", precvpriv->read_port_complete_EINPROGRESS_cnt);
++	len += snprintf(page + len, count - len, "read_port_complete_other_urb_err_cnt=%d\n", precvpriv->read_port_complete_other_urb_err_cnt);
++	len += snprintf(page + len, count - len, "hw_init_completed=%d\n", padapter->hw_init_completed);
++#ifdef CONFIG_USB_HCI
++	len += snprintf(page + len, count - len, "continual_urb_error=%d\n", atomic_read(&pdvobj->continual_urb_error));
++#endif
++
++        for(i = 0; i < 4; i++)
++	{
++		phwxmit = pxmitpriv->hwxmits + i;
++		len += snprintf(page + len, count - len, "%d, hwq.accnt=%d\n", i, phwxmit->accnt);
++	}
++
++	*eof = 1;
++	return len;
++
++}
++
++
++
++int proc_get_mac_reg_dump1(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1;
++
++	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
++
++	for(i=0x0;i<0x300;i+=4)
++	{
++		if(j%4==1)	len += snprintf(page + len, count - len,"0x%02x",i);
++		len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i));
++		if((j++)%4 == 0)	len += snprintf(page + len, count - len,"\n");
++	}
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_get_mac_reg_dump2(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1;
++
++	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
++	memset(page, 0, count);
++	for(i=0x300;i<0x600;i+=4)
++	{
++		if(j%4==1)	len += snprintf(page + len, count - len,"0x%02x",i);
++		len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i));
++		if((j++)%4 == 0)	len += snprintf(page + len, count - len,"\n");
++	}
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_get_mac_reg_dump3(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1;
++
++	len += snprintf(page + len, count - len, "\n======= MAC REG =======\n");
++
++	for(i=0x600;i<0x800;i+=4)
++	{
++		if(j%4==1)	len += snprintf(page + len, count - len,"0x%02x",i);
++		len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i));
++		if((j++)%4 == 0)	len += snprintf(page + len, count - len,"\n");
++	}
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_get_bb_reg_dump1(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1;
++
++	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
++	for(i=0x800;i<0xB00;i+=4)
++	{
++		if(j%4==1) 	len += snprintf(page + len, count - len,"0x%02x",i);
++		len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i));
++		if((j++)%4 == 0)	len += snprintf(page + len, count - len,"\n");
++	}
++	*eof = 1;
++	return len;
++}
++
++int proc_get_bb_reg_dump2(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1;
++
++	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
++	for(i=0xB00;i<0xE00;i+=4)
++	{
++		if(j%4==1) 	len += snprintf(page + len, count - len,"0x%02x",i);
++		len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i));
++		if((j++)%4 == 0)	len += snprintf(page + len, count - len,"\n");
++	}
++	*eof = 1;
++	return len;
++}
++
++int proc_get_bb_reg_dump3(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1;
++
++	len += snprintf(page + len, count - len, "\n======= BB REG =======\n");
++	for(i=0xE00;i<0x1000;i+=4)
++	{
++		if(j%4==1) 	len += snprintf(page + len, count - len,"0x%02x",i);
++		len += snprintf(page + len, count - len," 0x%08x ",rtw_read32(padapter,i));
++		if((j++)%4 == 0)	len += snprintf(page + len, count - len,"\n");
++	}
++	*eof = 1;
++	return len;
++}
++
++int proc_get_rf_reg_dump1(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1,path;
++	u32 value;
++
++	len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
++	path = 1;
++	len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path);
++	for(i=0;i<0xC0;i++)
++	{
++		//value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord);
++		value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
++		if(j%4==1)	len += snprintf(page + len, count - len, "0x%02x ",i);
++		len += snprintf(page + len, count - len, " 0x%08x ",value);
++		if((j++)%4==0)	len += snprintf(page + len, count - len, "\n");
++	}
++
++	*eof = 1;
++	return len;
++}
++
++
++int proc_get_rf_reg_dump2(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1,path;
++	u32 value;
++
++	len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
++	path = 1;
++	len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path);
++	for(i=0xC0;i<0x100;i++)
++	{
++		//value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord);
++		value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
++		if(j%4==1)	len += snprintf(page + len, count - len, "0x%02x ",i);
++		len += snprintf(page + len, count - len, " 0x%08x ",value);
++		if((j++)%4==0)	len += snprintf(page + len, count - len, "\n");
++	}
++	*eof = 1;
++	return len;
++}
++
++
++int proc_get_rf_reg_dump3(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1,path;
++	u32 value;
++
++	len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
++	path = 2;
++	len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path);
++	for(i=0;i<0xC0;i++)
++	{
++		//value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord);
++		value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
++		if(j%4==1)	len += snprintf(page + len, count - len, "0x%02x ",i);
++		len += snprintf(page + len, count - len, " 0x%08x ",value);
++		if((j++)%4==0)	len += snprintf(page + len, count - len, "\n");
++	}
++
++	*eof = 1;
++	return len;
++}
++
++
++int proc_get_rf_reg_dump4(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++	int i,j=1,path;
++	u32 value;
++
++	len += snprintf(page + len, count - len, "\n======= RF REG =======\n");
++	path = 2;
++	len += snprintf(page + len, count - len, "\nRF_Path(%x)\n",path);
++	for(i=0xC0;i<0x100;i++)
++	{
++		//value = PHY_QueryRFReg(padapter, (RF90_RADIO_PATH_E)path,i, bMaskDWord);
++		value =rtw_hal_read_rfreg(padapter, path, i, 0xffffffff);
++		if(j%4==1)	len += snprintf(page + len, count - len, "0x%02x ",i);
++		len += snprintf(page + len, count - len, " 0x%08x ",value);
++		if((j++)%4==0)	len += snprintf(page + len, count - len, "\n");
++	}
++	*eof = 1;
++	return len;
++}
++
++
++
++int proc_get_rx_signal(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len,
++		"rssi:%d\n"
++		"rxpwdb:%d\n"
++		"signal_strength:%u\n"
++		"signal_qual:%u\n"
++		"noise:%u\n",
++		padapter->recvpriv.rssi,
++		padapter->recvpriv.rxpwdb,
++		padapter->recvpriv.signal_strength,
++		padapter->recvpriv.signal_qual,
++		padapter->recvpriv.noise
++		);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_rx_signal(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	char tmp[32];
++	u32 is_signal_dbg, signal_strength;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%u %u", &is_signal_dbg, &signal_strength);
++
++		is_signal_dbg = is_signal_dbg==0?0:1;
++
++		if(is_signal_dbg && num!=2)
++			return count;
++
++		signal_strength = signal_strength>100?100:signal_strength;
++		signal_strength = signal_strength<0?0:signal_strength;
++
++		padapter->recvpriv.is_signal_dbg = is_signal_dbg;
++		padapter->recvpriv.signal_strength_dbg=signal_strength;
++
++		if(is_signal_dbg)
++			DBG_871X("set %s %u\n", "DBG_SIGNAL_STRENGTH", signal_strength);
++		else
++			DBG_871X("set %s\n", "HW_SIGNAL_STRENGTH");
++
++	}
++
++	return count;
++
++}
++
++int proc_get_ht_enable(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++
++	int len = 0;
++
++	if(pregpriv)
++		len += snprintf(page + len, count - len,
++			"%d\n",
++			pregpriv->ht_enable
++			);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_ht_enable(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++	char tmp[32];
++	u32 mode;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%d ", &mode);
++
++		if( pregpriv && mode >= 0 && mode < 2 )
++		{
++			pregpriv->ht_enable= mode;
++			printk("ht_enable=%d\n", pregpriv->ht_enable);
++		}
++	}
++
++	return count;
++
++}
++
++
++int proc_get_cbw40_enable(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++
++	int len = 0;
++
++	if(pregpriv)
++		len += snprintf(page + len, count - len,
++			"%d\n",
++			pregpriv->cbw40_enable
++			);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_cbw40_enable(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++	char tmp[32];
++	u32 mode;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%d ", &mode);
++
++		if( pregpriv && mode >= 0 && mode < 2 )
++		{
++			pregpriv->cbw40_enable= mode;
++			printk("cbw40_enable=%d\n", mode);
++		}
++	}
++
++	return count;
++
++}
++
++int proc_get_ampdu_enable(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++
++	int len = 0;
++
++	if(pregpriv)
++		len += snprintf(page + len, count - len,
++			"%d\n",
++			pregpriv->ampdu_enable
++			);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_ampdu_enable(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++	char tmp[32];
++	u32 mode;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%d ", &mode);
++
++		if( pregpriv && mode >= 0 && mode < 3 )
++		{
++			pregpriv->ampdu_enable= mode;
++			printk("ampdu_enable=%d\n", mode);
++		}
++	}
++
++	return count;
++
++}
++
++
++int proc_get_two_path_rssi(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++
++	int len = 0;
++
++	if(padapter)
++		len += snprintf(page + len, count - len,
++			"%d %d\n",
++			padapter->recvpriv.RxRssi[0],
++			padapter->recvpriv.RxRssi[1]
++			);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_rx_stbc(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++
++	int len = 0;
++
++	if(pregpriv)
++		len += snprintf(page + len, count - len,
++			"%d\n",
++			pregpriv->rx_stbc
++			);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_rx_stbc(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++	char tmp[32];
++	u32 mode;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%d ", &mode);
++
++		if( pregpriv && (mode == 0 || mode == 1|| mode == 2|| mode == 3))
++		{
++			pregpriv->rx_stbc= mode;
++			printk("rx_stbc=%d\n", mode);
++		}
++	}
++
++	return count;
++
++}
++
++int proc_get_vid(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	u16 VID=0;
++	int len = 0;
++
++	rtw_hal_get_hwreg(padapter, HW_VAR_VID, (u8 *)&VID);
++	len += snprintf(page + len, count - len,
++		"%04x\n",
++		VID
++		);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_pid(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	u16 PID=0;
++	int len = 0;
++
++	rtw_hal_get_hwreg(padapter, HW_VAR_PID, (u8 *)&PID);
++	len += snprintf(page + len, count - len,
++		"%04x\n",
++		PID
++		);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_get_rssi_disp(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	*eof = 1;
++	return 0;
++}
++
++int proc_set_rssi_disp(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	char tmp[32];
++	u32 enable=0;
++
++	if (count < 1)
++	{
++		DBG_8192C("argument size is less than 1\n");
++		return -EFAULT;
++	}
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%x", &enable);
++
++		if (num !=  1) {
++			DBG_8192C("invalid set_rssi_disp parameter!\n");
++			return count;
++		}
++
++		if(enable)
++		{
++			DBG_8192C("Turn On Rx RSSI Display Function\n");
++			padapter->bRxRSSIDisplay = enable ;
++		}
++		else
++		{
++			DBG_8192C("Turn Off Rx RSSI Display Function\n");
++			padapter->bRxRSSIDisplay = 0 ;
++		}
++
++	}
++
++	return count;
++
++}
++
++
++#ifdef CONFIG_AP_MODE
++
++int proc_get_all_sta_info(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	_irqL irqL;
++	struct sta_info *psta;
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	int i, j;
++	_list	*plist, *phead;
++	struct recv_reorder_ctrl *preorder_ctrl;
++	int len = 0;
++
++
++	len += snprintf(page + len, count - len, "sta_dz_bitmap=0x%x, tim_bitmap=0x%x\n", pstapriv->sta_dz_bitmap, pstapriv->tim_bitmap);
++
++	_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
++
++	for(i=0; i< NUM_STA; i++)
++	{
++		phead = &(pstapriv->sta_hash[i]);
++		plist = get_next(phead);
++
++		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
++		{
++			psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
++
++			plist = get_next(plist);
++
++			//if(extra_arg == psta->aid)
++			{
++				len += snprintf(page + len, count - len, "sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->hwaddr));
++				len += snprintf(page + len, count - len, "rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
++				len += snprintf(page + len, count - len, "qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
++				len += snprintf(page + len, count - len, "state=0x%x, aid=%d, macid=%d, raid=%d\n", psta->state, psta->aid, psta->mac_id, psta->raid);
++				len += snprintf(page + len, count - len, "bwmode=%d, ch_offset=%d, sgi=%d\n", psta->htpriv.bwmode, psta->htpriv.ch_offset, psta->htpriv.sgi);
++				len += snprintf(page + len, count - len, "ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
++				len += snprintf(page + len, count - len, "agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
++				len += snprintf(page + len, count - len, "sleepq_len=%d\n", psta->sleepq_len);
++				len += snprintf(page + len, count - len, "capability=0x%x\n", psta->capability);
++				len += snprintf(page + len, count - len, "flags=0x%x\n", psta->flags);
++				len += snprintf(page + len, count - len, "wpa_psk=0x%x\n", psta->wpa_psk);
++				len += snprintf(page + len, count - len, "wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
++				len += snprintf(page + len, count - len, "wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
++				len += snprintf(page + len, count - len, "qos_info=0x%x\n", psta->qos_info);
++				len += snprintf(page + len, count - len, "dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
++
++				for(j=0;j<16;j++)
++				{
++					preorder_ctrl = &psta->recvreorder_ctrl[j];
++					if(preorder_ctrl->enable)
++					{
++						len += snprintf(page + len, count - len, "tid=%d, indicate_seq=%d\n", j, preorder_ctrl->indicate_seq);
++					}
++				}
++
++			}
++
++		}
++
++	}
++
++	_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
++
++	*eof = 1;
++	return len;
++
++}
++
++#endif
++
++#ifdef DBG_MEMORY_LEAK
++#include <asm/atomic.h>
++extern atomic_t _malloc_cnt;;
++extern atomic_t _malloc_size;;
++
++int proc_get_malloc_cnt(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++
++	int len = 0;
++
++	len += snprintf(page + len, count - len, "_malloc_cnt=%d\n", atomic_read(&_malloc_cnt));
++	len += snprintf(page + len, count - len, "_malloc_size=%d\n", atomic_read(&_malloc_size));
++
++	*eof = 1;
++	return len;
++}
++#endif /* DBG_MEMORY_LEAK */
++
++#ifdef CONFIG_FIND_BEST_CHANNEL
++int proc_get_best_channel(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	int len = 0;
++	u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
++
++	for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
++		if ( pmlmeext->channel_set[i].ChannelNum == 1)
++			index_24G = i;
++		if ( pmlmeext->channel_set[i].ChannelNum == 36)
++			index_5G = i;
++	}
++
++	for (i=0; pmlmeext->channel_set[i].ChannelNum !=0; i++) {
++		// 2.4G
++		if ( pmlmeext->channel_set[i].ChannelNum == 6 ) {
++			if ( pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count ) {
++				index_24G = i;
++				best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
++			}
++		}
++
++		// 5G
++		if ( pmlmeext->channel_set[i].ChannelNum >= 36
++			&& pmlmeext->channel_set[i].ChannelNum < 140 ) {
++			 // Find primary channel
++			if ( (( pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0)
++				&& (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) {
++				index_5G = i;
++				best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
++			}
++		}
++
++		if ( pmlmeext->channel_set[i].ChannelNum >= 149
++			&& pmlmeext->channel_set[i].ChannelNum < 165) {
++			 // find primary channel
++			if ( (( pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0)
++				&& (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count) ) {
++				index_5G = i;
++				best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
++			}
++		}
++#if 1 // debug
++		len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n",
++					pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count);
++#endif
++	}
++
++	len += snprintf(page + len, count - len, "best_channel_5G = %d\n", best_channel_5G);
++	len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G);
++
++	*eof = 1;
++	return len;
++
++}
++
++int proc_set_best_channel(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	char tmp[32];
++
++	if(count < 1)
++		return -EFAULT;
++
++	if(buffer && !copy_from_user(tmp, buffer, sizeof(tmp)))
++	{
++		int i;
++		for(i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++)
++		{
++			pmlmeext->channel_set[i].rx_count = 0;
++		}
++
++		DBG_871X("set %s\n", "Clean Best Channel Count");
++	}
++
++	return count;
++}
++#endif /* CONFIG_FIND_BEST_CHANNEL */
++
++#if defined(DBG_CONFIG_ERROR_DETECT)
++#include <rtw_sreset.h>
++int proc_get_sreset(char *page, char **start, off_t offset, int count, int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++	int len = 0;
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_sreset(struct file *file, const char *buffer, unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	char tmp[32];
++	s32 trigger_point;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%d", &trigger_point);
++
++		if (trigger_point == SRESET_TGP_NULL)
++			rtw_hal_sreset_reset(padapter);
++		else
++			sreset_set_trigger_point(padapter, trigger_point);
++	}
++
++	return count;
++
++}
++#endif /* DBG_CONFIG_ERROR_DETECT */
++
++#ifdef CONFIG_DM_ADAPTIVITY
++int proc_get_dm_adaptivity(char *page, char **start,
++			  off_t offset, int count,
++			  int *eof, void *data)
++{
++	struct net_device *dev = data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	int len = 0;
++
++	len += dm_adaptivity_get_parm_str(padapter, page, count);
++
++	*eof = 1;
++	return len;
++}
++
++int proc_set_dm_adaptivity(struct file *file, const char *buffer,
++		unsigned long count, void *data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
++	char tmp[32];
++	u32 TH_L2H_ini;
++	s8 TH_EDCCA_HL_diff;
++	u32 IGI_Base;
++	int ForceEDCCA;
++	u8 AdapEn_RSSI;
++	u8 IGI_LowerBound;
++
++	if (count < 1)
++		return -EFAULT;
++
++	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
++
++		int num = sscanf(tmp, "%x %hhd %x %d %hhu %hhu",
++			&TH_L2H_ini, &TH_EDCCA_HL_diff, &IGI_Base, &ForceEDCCA, &AdapEn_RSSI, &IGI_LowerBound);
++
++		if (num != 6)
++			return count;
++
++		dm_adaptivity_set_parm(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)IGI_Base, (bool)ForceEDCCA, AdapEn_RSSI, IGI_LowerBound);
++	}
++
++	return count;
++}
++#endif /* CONFIG_DM_ADAPTIVITY */
++
++#endif
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_eeprom.c
+@@ -0,0 +1,422 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_EEPROM_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++
++void up_clk(_adapter*	padapter,	 u16 *x)
++{
++_func_enter_;
++	*x = *x | _EESK;
++	rtw_write8(padapter, EE_9346CR, (u8)*x);
++	rtw_udelay_os(CLOCK_RATE);
++
++_func_exit_;
++
++}
++
++void down_clk(_adapter *	padapter, u16 *x	)
++{
++_func_enter_;
++	*x = *x & ~_EESK;
++	rtw_write8(padapter, EE_9346CR, (u8)*x);
++	rtw_udelay_os(CLOCK_RATE);
++_func_exit_;
++}
++
++void shift_out_bits(_adapter * padapter, u16 data, u16 count)
++{
++	u16 x,mask;
++_func_enter_;
++
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	mask = 0x01 << (count - 1);
++	x = rtw_read8(padapter, EE_9346CR);
++
++	x &= ~(_EEDO | _EEDI);
++
++	do
++	{
++		x &= ~_EEDI;
++		if(data & mask)
++			x |= _EEDI;
++		if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++		}
++		rtw_write8(padapter, EE_9346CR, (u8)x);
++		rtw_udelay_os(CLOCK_RATE);
++		up_clk(padapter, &x);
++		down_clk(padapter, &x);
++		mask = mask >> 1;
++	} while(mask);
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	x &= ~_EEDI;
++	rtw_write8(padapter, EE_9346CR, (u8)x);
++out:
++_func_exit_;
++}
++
++u16 shift_in_bits (_adapter * padapter)
++{
++	u16 x,d=0,i;
++_func_enter_;
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	x = rtw_read8(padapter, EE_9346CR);
++
++	x &= ~( _EEDO | _EEDI);
++	d = 0;
++
++	for(i=0; i<16; i++)
++	{
++		d = d << 1;
++		up_clk(padapter, &x);
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++		x = rtw_read8(padapter, EE_9346CR);
++
++		x &= ~(_EEDI);
++		if(x & _EEDO)
++		d |= 1;
++
++		down_clk(padapter, &x);
++	}
++out:
++_func_exit_;
++
++	return d;
++}
++
++void standby(_adapter *	padapter	)
++{
++	u8   x;
++_func_enter_;
++	x = rtw_read8(padapter, EE_9346CR);
++
++	x &= ~(_EECS | _EESK);
++	rtw_write8(padapter, EE_9346CR,x);
++
++	rtw_udelay_os(CLOCK_RATE);
++	x |= _EECS;
++	rtw_write8(padapter, EE_9346CR, x);
++	rtw_udelay_os(CLOCK_RATE);
++_func_exit_;
++}
++
++u16 wait_eeprom_cmd_done(_adapter* padapter)
++{
++	u8 	x;
++	u16	i,res=_FALSE;
++_func_enter_;
++	standby(padapter );
++	for (i=0; i<200; i++)
++	{
++		x = rtw_read8(padapter, EE_9346CR);
++		if (x & _EEDO){
++			res=_TRUE;
++			goto exit;
++			}
++		rtw_udelay_os(CLOCK_RATE);
++	}
++exit:
++_func_exit_;
++	return res;
++}
++
++void eeprom_clean(_adapter * padapter)
++{
++	u16 x;
++_func_enter_;
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	x = rtw_read8(padapter, EE_9346CR);
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	x &= ~(_EECS | _EEDI);
++	rtw_write8(padapter, EE_9346CR, (u8)x);
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	up_clk(padapter, &x);
++		if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	down_clk(padapter, &x);
++out:
++_func_exit_;
++}
++
++void eeprom_write16(_adapter * padapter, u16 reg, u16 data)
++{
++	u8 x;
++#ifdef CONFIG_RTL8712
++	u8	tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new;
++	tmp8_ori=rtw_read8(padapter, 0x102502f1);
++	tmp8_new=tmp8_ori & 0xf7;
++	if(tmp8_ori != tmp8_new){
++		rtw_write8(padapter, 0x102502f1, tmp8_new);
++		RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n"));
++	}
++	tmp8_clk_ori=rtw_read8(padapter,0x10250003);
++	tmp8_clk_new=tmp8_clk_ori|0x20;
++	if(tmp8_clk_new!=tmp8_clk_ori){
++		RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n"));
++		rtw_write8(padapter, 0x10250003, tmp8_clk_new);
++	}
++#endif
++_func_enter_;
++
++	x = rtw_read8(padapter, EE_9346CR);
++
++	x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
++	x |= _EEM1 | _EECS;
++	rtw_write8(padapter, EE_9346CR, x);
++
++	shift_out_bits(padapter, EEPROM_EWEN_OPCODE, 5);
++
++	if(padapter->EepromAddressSize==8)	//CF+ and SDIO
++		shift_out_bits(padapter, 0, 6);
++	else									//USB
++		shift_out_bits(padapter, 0, 4);
++
++	standby( padapter);
++
++// Commented out by rcnjko, 2004.0
++//	// Erase this particular word.  Write the erase opcode and register
++//	// number in that order. The opcode is 3bits in length; reg is 6 bits long.
++//	shift_out_bits(Adapter, EEPROM_ERASE_OPCODE, 3);
++//	shift_out_bits(Adapter, reg, Adapter->EepromAddressSize);
++//
++//	if (wait_eeprom_cmd_done(Adapter ) == FALSE)
++//	{
++//		return;
++//	}
++
++
++	standby(padapter );
++
++	// write the new word to the EEPROM
++
++	// send the write opcode the EEPORM
++	shift_out_bits(padapter, EEPROM_WRITE_OPCODE, 3);
++
++	// select which word in the EEPROM that we are writing to.
++	shift_out_bits(padapter, reg, padapter->EepromAddressSize);
++
++	// write the data to the selected EEPROM word.
++	shift_out_bits(padapter, data, 16);
++
++	if (wait_eeprom_cmd_done(padapter ) == _FALSE)
++	{
++
++		goto exit;
++	}
++
++	standby(padapter );
++
++	shift_out_bits(padapter, EEPROM_EWDS_OPCODE, 5);
++	shift_out_bits(padapter, reg, 4);
++
++	eeprom_clean(padapter );
++exit:
++#ifdef CONFIG_RTL8712
++	if(tmp8_clk_new!=tmp8_clk_ori)
++		rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
++	if(tmp8_new!=tmp8_ori)
++		rtw_write8(padapter, 0x102502f1, tmp8_ori);
++
++#endif
++_func_exit_;
++	return;
++}
++
++u16 eeprom_read16(_adapter * padapter, u16 reg) //ReadEEprom
++{
++
++	u16 x;
++	u16 data=0;
++#ifdef CONFIG_RTL8712
++	u8	tmp8_ori,tmp8_new,tmp8_clk_ori,tmp8_clk_new;
++	tmp8_ori= rtw_read8(padapter, 0x102502f1);
++	tmp8_new = tmp8_ori & 0xf7;
++	if(tmp8_ori != tmp8_new){
++		rtw_write8(padapter, 0x102502f1, tmp8_new);
++		RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x102502f1=====\n"));
++	}
++	tmp8_clk_ori=rtw_read8(padapter,0x10250003);
++	tmp8_clk_new=tmp8_clk_ori|0x20;
++	if(tmp8_clk_new!=tmp8_clk_ori){
++		RT_TRACE(_module_rtl871x_mp_ioctl_c_,_drv_err_,("====write 0x10250003=====\n"));
++		rtw_write8(padapter, 0x10250003, tmp8_clk_new);
++	}
++#endif
++_func_enter_;
++
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	// select EEPROM, reset bits, set _EECS
++	x = rtw_read8(padapter, EE_9346CR);
++
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++
++	x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
++	x |= _EEM1 | _EECS;
++	rtw_write8(padapter, EE_9346CR, (unsigned char)x);
++
++	// write the read opcode and register number in that order
++	// The opcode is 3bits in length, reg is 6 bits long
++	shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
++	shift_out_bits(padapter, reg, padapter->EepromAddressSize);
++
++	// Now read the data (16 bits) in from the selected EEPROM word
++	data = shift_in_bits(padapter);
++
++	eeprom_clean(padapter);
++out:
++#ifdef CONFIG_RTL8712
++	if(tmp8_clk_new!=tmp8_clk_ori)
++		rtw_write8(padapter, 0x10250003, tmp8_clk_ori);
++	if(tmp8_new!=tmp8_ori)
++		rtw_write8(padapter, 0x102502f1, tmp8_ori);
++
++#endif
++_func_exit_;
++	return data;
++
++
++}
++
++
++
++
++//From even offset
++void eeprom_read_sz(_adapter * padapter, u16 reg, u8* data, u32 sz)
++{
++
++	u16 x, data16;
++	u32 i;
++_func_enter_;
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++	// select EEPROM, reset bits, set _EECS
++	x = rtw_read8(padapter, EE_9346CR);
++
++	if(padapter->bSurpriseRemoved==_TRUE){
++		RT_TRACE(_module_rtl871x_eeprom_c_,_drv_err_,("padapter->bSurpriseRemoved==_TRUE"));
++		goto out;
++	}
++
++	x &= ~(_EEDI | _EEDO | _EESK | _EEM0);
++	x |= _EEM1 | _EECS;
++	rtw_write8(padapter, EE_9346CR, (unsigned char)x);
++
++	// write the read opcode and register number in that order
++	// The opcode is 3bits in length, reg is 6 bits long
++	shift_out_bits(padapter, EEPROM_READ_OPCODE, 3);
++	shift_out_bits(padapter, reg, padapter->EepromAddressSize);
++
++
++	for(i=0; i<sz; i+=2)
++	{
++		data16 = shift_in_bits(padapter);
++		data[i] = data16 & 0xff;
++		data[i+1] = data16 >>8;
++	}
++
++	eeprom_clean(padapter);
++out:
++_func_exit_;
++
++
++
++}
++
++
++//addr_off : address offset of the entry in eeprom (not the tuple number of eeprom (reg); that is addr_off !=reg)
++u8 eeprom_read(_adapter * padapter, u32 addr_off, u8 sz, u8* rbuf)
++{
++	u8 quotient, remainder, addr_2align_odd;
++	u16 reg, stmp , i=0, idx = 0;
++_func_enter_;
++	reg = (u16)(addr_off >> 1);
++	addr_2align_odd = (u8)(addr_off & 0x1);
++
++	if(addr_2align_odd) //read that start at high part: e.g  1,3,5,7,9,...
++	{
++		stmp = eeprom_read16(padapter, reg);
++		rbuf[idx++] = (u8) ((stmp>>8)&0xff); //return hogh-part of the short
++		reg++; sz--;
++	}
++
++	quotient = sz >> 1;
++	remainder = sz & 0x1;
++
++	for( i=0 ; i < quotient; i++)
++	{
++		stmp = eeprom_read16(padapter, reg+i);
++		rbuf[idx++] = (u8) (stmp&0xff);
++		rbuf[idx++] = (u8) ((stmp>>8)&0xff);
++	}
++
++	reg = reg+i;
++	if(remainder){ //end of read at lower part of short : 0,2,4,6,...
++		stmp = eeprom_read16(padapter, reg);
++		rbuf[idx] = (u8)(stmp & 0xff);
++	}
++_func_exit_;
++	return _TRUE;
++}
++
++
++
++VOID read_eeprom_content(_adapter *	padapter)
++{
++
++_func_enter_;
++
++
++_func_exit_;
++}
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ieee80211.c
+@@ -0,0 +1,1914 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _IEEE80211_C
++
++#include <drv_types.h>
++#include <ieee80211.h>
++#include <wifi.h>
++#include <osdep_service.h>
++#include <wlan_bssdef.h>
++
++u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
++u16 RTW_WPA_VERSION = 1;
++u8 WPA_AUTH_KEY_MGMT_NONE[] = { 0x00, 0x50, 0xf2, 0 };
++u8 WPA_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x50, 0xf2, 1 };
++u8 WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x50, 0xf2, 2 };
++u8 WPA_CIPHER_SUITE_NONE[] = { 0x00, 0x50, 0xf2, 0 };
++u8 WPA_CIPHER_SUITE_WEP40[] = { 0x00, 0x50, 0xf2, 1 };
++u8 WPA_CIPHER_SUITE_TKIP[] = { 0x00, 0x50, 0xf2, 2 };
++u8 WPA_CIPHER_SUITE_WRAP[] = { 0x00, 0x50, 0xf2, 3 };
++u8 WPA_CIPHER_SUITE_CCMP[] = { 0x00, 0x50, 0xf2, 4 };
++u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
++
++u16 RSN_VERSION_BSD = 1;
++u8 RSN_AUTH_KEY_MGMT_UNSPEC_802_1X[] = { 0x00, 0x0f, 0xac, 1 };
++u8 RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X[] = { 0x00, 0x0f, 0xac, 2 };
++u8 RSN_CIPHER_SUITE_NONE[] = { 0x00, 0x0f, 0xac, 0 };
++u8 RSN_CIPHER_SUITE_WEP40[] = { 0x00, 0x0f, 0xac, 1 };
++u8 RSN_CIPHER_SUITE_TKIP[] = { 0x00, 0x0f, 0xac, 2 };
++u8 RSN_CIPHER_SUITE_WRAP[] = { 0x00, 0x0f, 0xac, 3 };
++u8 RSN_CIPHER_SUITE_CCMP[] = { 0x00, 0x0f, 0xac, 4 };
++u8 RSN_CIPHER_SUITE_WEP104[] = { 0x00, 0x0f, 0xac, 5 };
++//-----------------------------------------------------------
++// for adhoc-master to generate ie and provide supported-rate to fw
++//-----------------------------------------------------------
++
++static u8 	WIFI_CCKRATES[] =
++{(IEEE80211_CCK_RATE_1MB | IEEE80211_BASIC_RATE_MASK),
++ (IEEE80211_CCK_RATE_2MB | IEEE80211_BASIC_RATE_MASK),
++ (IEEE80211_CCK_RATE_5MB | IEEE80211_BASIC_RATE_MASK),
++ (IEEE80211_CCK_RATE_11MB | IEEE80211_BASIC_RATE_MASK)};
++
++static u8 	WIFI_OFDMRATES[] =
++{(IEEE80211_OFDM_RATE_6MB),
++ (IEEE80211_OFDM_RATE_9MB),
++ (IEEE80211_OFDM_RATE_12MB),
++ (IEEE80211_OFDM_RATE_18MB),
++ (IEEE80211_OFDM_RATE_24MB),
++ IEEE80211_OFDM_RATE_36MB,
++ IEEE80211_OFDM_RATE_48MB,
++ IEEE80211_OFDM_RATE_54MB};
++
++
++int rtw_get_bit_value_from_ieee_value(u8 val)
++{
++	unsigned char dot11_rate_table[]={2,4,11,22,12,18,24,36,48,72,96,108,0}; // last element must be zero!!
++
++	int i=0;
++	while(dot11_rate_table[i] != 0) {
++		if (dot11_rate_table[i] == val)
++			return BIT(i);
++		i++;
++	}
++	return 0;
++}
++
++uint	rtw_is_cckrates_included(u8 *rate)
++{
++		u32	i = 0;
++
++		while(rate[i]!=0)
++		{
++			if  (  (((rate[i]) & 0x7f) == 2)	|| (((rate[i]) & 0x7f) == 4) ||
++			(((rate[i]) & 0x7f) == 11)  || (((rate[i]) & 0x7f) == 22) )
++			return _TRUE;
++			i++;
++		}
++
++		return _FALSE;
++}
++
++uint	rtw_is_cckratesonly_included(u8 *rate)
++{
++	u32 i = 0;
++
++
++	while(rate[i]!=0)
++	{
++			if  (  (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
++				(((rate[i]) & 0x7f) != 11)  && (((rate[i]) & 0x7f) != 22) )
++
++			return _FALSE;
++
++			i++;
++	}
++
++	return _TRUE;
++
++}
++
++int rtw_check_network_type(unsigned char *rate, int ratelen, int channel)
++{
++	if (channel > 14)
++	{
++		if ((rtw_is_cckrates_included(rate)) == _TRUE)
++			return WIRELESS_INVALID;
++		else
++			return WIRELESS_11A;
++	}
++	else  // could be pure B, pure G, or B/G
++	{
++		if ((rtw_is_cckratesonly_included(rate)) == _TRUE)
++			return WIRELESS_11B;
++		else if((rtw_is_cckrates_included(rate)) == _TRUE)
++			return 	WIRELESS_11BG;
++		else
++			return WIRELESS_11G;
++	}
++
++}
++
++u8 *rtw_set_fixed_ie(unsigned char *pbuf, unsigned int len, unsigned char *source,
++				unsigned int *frlen)
++{
++	_rtw_memcpy((void *)pbuf, (void *)source, len);
++	*frlen = *frlen + len;
++	return (pbuf + len);
++}
++
++// rtw_set_ie will update frame length
++u8 *rtw_set_ie
++(
++	u8 *pbuf,
++	sint index,
++	uint len,
++	u8 *source,
++	uint *frlen //frame length
++)
++{
++_func_enter_;
++	*pbuf = (u8)index;
++
++	*(pbuf + 1) = (u8)len;
++
++	if (len > 0)
++		_rtw_memcpy((void *)(pbuf + 2), (void *)source, len);
++
++	*frlen = *frlen + (len + 2);
++
++	return (pbuf + len + 2);
++_func_exit_;
++}
++
++inline u8 *rtw_set_ie_ch_switch(u8 *buf, u32 *buf_len, u8 ch_switch_mode,
++	u8 new_ch, u8 ch_switch_cnt)
++{
++	u8 ie_data[3];
++
++	ie_data[0] = ch_switch_mode;
++	ie_data[1] = new_ch;
++	ie_data[2] = ch_switch_cnt;
++	return rtw_set_ie(buf, WLAN_EID_CHANNEL_SWITCH,  3, ie_data, buf_len);
++}
++
++inline u8 secondary_ch_offset_to_hal_ch_offset(u8 ch_offset)
++{
++	if (ch_offset == SCN)
++		return HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++	else if(ch_offset == SCA)
++		return HAL_PRIME_CHNL_OFFSET_UPPER;
++	else if(ch_offset == SCB)
++		return HAL_PRIME_CHNL_OFFSET_LOWER;
++
++	return HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++}
++
++inline u8 hal_ch_offset_to_secondary_ch_offset(u8 ch_offset)
++{
++	if (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
++		return SCN;
++	else if(ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
++		return SCB;
++	else if(ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
++		return SCA;
++
++	return SCN;
++}
++
++inline u8 *rtw_set_ie_secondary_ch_offset(u8 *buf, u32 *buf_len, u8 secondary_ch_offset)
++{
++	return rtw_set_ie(buf, WLAN_EID_SECONDARY_CHANNEL_OFFSET,  1, &secondary_ch_offset, buf_len);
++}
++
++inline u8 *rtw_set_ie_mesh_ch_switch_parm(u8 *buf, u32 *buf_len, u8 ttl,
++	u8 flags, u16 reason, u16 precedence)
++{
++	u8 ie_data[6];
++
++	ie_data[0] = ttl;
++	ie_data[1] = flags;
++	RTW_PUT_LE16((u8*)&ie_data[2], reason);
++	RTW_PUT_LE16((u8*)&ie_data[4], precedence);
++
++	return rtw_set_ie(buf, 0x118,  6, ie_data, buf_len);
++}
++
++/*----------------------------------------------------------------------------
++index: the information element id index, limit is the limit for search
++-----------------------------------------------------------------------------*/
++u8 *rtw_get_ie(u8 *pbuf, sint index, sint *len, sint limit)
++{
++	sint tmp,i;
++	u8 *p;
++_func_enter_;
++	if (limit < 1){
++		_func_exit_;
++		return NULL;
++	}
++
++	p = pbuf;
++	i = 0;
++	*len = 0;
++	while(1)
++	{
++		if (*p == index)
++		{
++			*len = *(p + 1);
++			return (p);
++		}
++		else
++		{
++			tmp = *(p + 1);
++			p += (tmp + 2);
++			i += (tmp + 2);
++		}
++		if (i >= limit)
++			break;
++	}
++_func_exit_;
++	return NULL;
++}
++
++/**
++ * rtw_get_ie_ex - Search specific IE from a series of IEs
++ * @in_ie: Address of IEs to search
++ * @in_len: Length limit from in_ie
++ * @eid: Element ID to match
++ * @oui: OUI to match
++ * @oui_len: OUI length
++ * @ie: If not NULL and the specific IE is found, the IE will be copied to the buf starting from the specific IE
++ * @ielen: If not NULL and the specific IE is found, will set to the length of the entire IE
++ *
++ * Returns: The address of the specific IE found, or NULL
++ */
++u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, uint *ielen)
++{
++	uint cnt;
++	u8 *target_ie = NULL;
++
++
++	if(ielen)
++		*ielen = 0;
++
++	if(!in_ie || in_len<=0)
++		return target_ie;
++
++	cnt = 0;
++
++	while(cnt<in_len)
++	{
++		if(eid == in_ie[cnt]
++			&& ( !oui || _rtw_memcmp(&in_ie[cnt+2], oui, oui_len) == _TRUE))
++		{
++			target_ie = &in_ie[cnt];
++
++			if(ie)
++				_rtw_memcpy(ie, &in_ie[cnt], in_ie[cnt+1]+2);
++
++			if(ielen)
++				*ielen = in_ie[cnt+1]+2;
++
++			break;
++		}
++		else
++		{
++			cnt+=in_ie[cnt+1]+2; //goto next
++		}
++
++	}
++
++	return target_ie;
++}
++
++/**
++ * rtw_ies_remove_ie - Find matching IEs and remove
++ * @ies: Address of IEs to search
++ * @ies_len: Pointer of length of ies, will update to new length
++ * @offset: The offset to start scarch
++ * @eid: Element ID to match
++ * @oui: OUI to match
++ * @oui_len: OUI length
++ *
++ * Returns: _SUCCESS: ies is updated, _FAIL: not updated
++ */
++int rtw_ies_remove_ie(u8 *ies, uint *ies_len, uint offset, u8 eid, u8 *oui, u8 oui_len)
++{
++	int ret = _FAIL;
++	u8 *target_ie;
++	u32 target_ielen;
++	u8 *start;
++	uint search_len;
++
++	if(!ies || !ies_len || *ies_len <= offset)
++		goto exit;
++
++	start = ies + offset;
++	search_len = *ies_len - offset;
++
++	while (1) {
++		target_ie = rtw_get_ie_ex(start, search_len, eid, oui, oui_len, NULL, &target_ielen);
++		if (target_ie && target_ielen) {
++			u8 buf[MAX_IE_SZ] = {0};
++			u8 *remain_ies = target_ie + target_ielen;
++			uint remain_len = search_len - (remain_ies - start);
++
++			_rtw_memcpy(buf, remain_ies, remain_len);
++			_rtw_memcpy(target_ie, buf, remain_len);
++			*ies_len = *ies_len - target_ielen;
++			ret = _SUCCESS;
++
++			start = target_ie;
++			search_len = remain_len;
++		} else {
++			break;
++		}
++	}
++exit:
++	return ret;
++}
++
++void rtw_set_supported_rate(u8* SupportedRates, uint mode)
++{
++_func_enter_;
++
++	_rtw_memset(SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
++
++	switch (mode)
++	{
++		case WIRELESS_11B:
++			_rtw_memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
++			break;
++
++		case WIRELESS_11G:
++		case WIRELESS_11A:
++		case WIRELESS_11_5N:
++		case WIRELESS_11A_5N://Todo: no basic rate for ofdm ?
++			_rtw_memcpy(SupportedRates, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
++			break;
++
++		case WIRELESS_11BG:
++		case WIRELESS_11G_24N:
++		case WIRELESS_11_24N:
++		case WIRELESS_11BG_24N:
++			_rtw_memcpy(SupportedRates, WIFI_CCKRATES, IEEE80211_CCK_RATE_LEN);
++			_rtw_memcpy(SupportedRates + IEEE80211_CCK_RATE_LEN, WIFI_OFDMRATES, IEEE80211_NUM_OFDM_RATESLEN);
++			break;
++
++	}
++_func_exit_;
++}
++
++uint	rtw_get_rateset_len(u8	*rateset)
++{
++	uint i = 0;
++_func_enter_;
++	while(1)
++	{
++		if ((rateset[i]) == 0)
++			break;
++
++		if (i > 12)
++			break;
++
++		i++;
++	}
++_func_exit_;
++	return i;
++}
++
++int rtw_generate_ie(struct registry_priv *pregistrypriv)
++{
++	u8	wireless_mode;
++	int 	sz = 0, rateLen;
++	WLAN_BSSID_EX*	pdev_network = &pregistrypriv->dev_network;
++	u8*	ie = pdev_network->IEs;
++
++_func_enter_;
++
++	//timestamp will be inserted by hardware
++	sz += 8;
++	ie += sz;
++
++	//beacon interval : 2bytes
++	*(u16*)ie = cpu_to_le16((u16)pdev_network->Configuration.BeaconPeriod);//BCN_INTERVAL;
++	sz += 2;
++	ie += 2;
++
++	//capability info
++	*(u16*)ie = 0;
++
++	*(u16*)ie |= cpu_to_le16(cap_IBSS);
++
++	if(pregistrypriv->preamble == PREAMBLE_SHORT)
++		*(u16*)ie |= cpu_to_le16(cap_ShortPremble);
++
++	if (pdev_network->Privacy)
++		*(u16*)ie |= cpu_to_le16(cap_Privacy);
++
++	sz += 2;
++	ie += 2;
++
++	//SSID
++	ie = rtw_set_ie(ie, _SSID_IE_, pdev_network->Ssid.SsidLength, pdev_network->Ssid.Ssid, &sz);
++
++	//supported rates
++	if(pregistrypriv->wireless_mode == WIRELESS_11ABGN)
++	{
++		if(pdev_network->Configuration.DSConfig > 14)
++			wireless_mode = WIRELESS_11A_5N;
++		else
++			wireless_mode = WIRELESS_11BG_24N;
++	}
++	else
++	{
++		wireless_mode = pregistrypriv->wireless_mode;
++	}
++
++	rtw_set_supported_rate(pdev_network->SupportedRates, wireless_mode) ;
++
++	rateLen = rtw_get_rateset_len(pdev_network->SupportedRates);
++
++	if (rateLen > 8)
++	{
++		ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, pdev_network->SupportedRates, &sz);
++		//ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz);
++	}
++	else
++	{
++		ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, pdev_network->SupportedRates, &sz);
++	}
++
++	//DS parameter set
++	ie = rtw_set_ie(ie, _DSSET_IE_, 1, (u8 *)&(pdev_network->Configuration.DSConfig), &sz);
++
++
++	//IBSS Parameter Set
++
++	ie = rtw_set_ie(ie, _IBSS_PARA_IE_, 2, (u8 *)&(pdev_network->Configuration.ATIMWindow), &sz);
++
++	if (rateLen > 8)
++	{
++		ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (pdev_network->SupportedRates + 8), &sz);
++	}
++
++
++	//HT Cap.
++	if(((pregistrypriv->wireless_mode&WIRELESS_11_5N)||(pregistrypriv->wireless_mode&WIRELESS_11_24N))
++		&& (pregistrypriv->ht_enable==_TRUE))
++	{
++		//todo:
++	}
++
++	//pdev_network->IELength =  sz; //update IELength
++
++_func_exit_;
++
++	//return _SUCCESS;
++
++	return sz;
++
++}
++
++unsigned char *rtw_get_wpa_ie(unsigned char *pie, int *wpa_ie_len, int limit)
++{
++	int len;
++	u16 val16;
++	unsigned char wpa_oui_type[] = {0x00, 0x50, 0xf2, 0x01};
++	u8 *pbuf = pie;
++
++	while(1)
++	{
++		pbuf = rtw_get_ie(pbuf, _WPA_IE_ID_, &len, limit);
++
++		if (pbuf) {
++
++			//check if oui matches...
++			if (_rtw_memcmp((pbuf + 2), wpa_oui_type, sizeof (wpa_oui_type)) == _FALSE) {
++
++				goto check_next_ie;
++			}
++
++			//check version...
++			_rtw_memcpy((u8 *)&val16, (pbuf + 6), sizeof(val16));
++
++			val16 = le16_to_cpu(val16);
++			if (val16 != 0x0001)
++				goto check_next_ie;
++
++			*wpa_ie_len = *(pbuf + 1);
++
++			return pbuf;
++		}
++		else {
++
++			*wpa_ie_len = 0;
++			return NULL;
++		}
++
++check_next_ie:
++
++		limit -= (2 + len);
++
++		if (limit <= 0)
++			break;
++
++		pbuf += (2 + len);
++	}
++
++	*wpa_ie_len = 0;
++
++	return NULL;
++}
++
++unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit)
++{
++
++	return rtw_get_ie(pie, _WPA2_IE_ID_,rsn_ie_len, limit);
++
++}
++
++int rtw_get_wpa_cipher_suite(u8 *s)
++{
++	if (_rtw_memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_NONE;
++	if (_rtw_memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_WEP40;
++	if (_rtw_memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_TKIP;
++	if (_rtw_memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_CCMP;
++	if (_rtw_memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_WEP104;
++
++	return 0;
++}
++
++int rtw_get_wpa2_cipher_suite(u8 *s)
++{
++	if (_rtw_memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_NONE;
++	if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_WEP40;
++	if (_rtw_memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_TKIP;
++	if (_rtw_memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_CCMP;
++	if (_rtw_memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == _TRUE)
++		return WPA_CIPHER_WEP104;
++
++	return 0;
++}
++
++
++int rtw_parse_wpa_ie(u8* wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwise_cipher)
++{
++	int i, ret=_SUCCESS;
++	int left, count;
++	u8 *pos;
++
++	if (wpa_ie_len <= 0) {
++		/* No WPA IE - fail silently */
++		return _FAIL;
++	}
++
++
++	if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) ||
++	   (_rtw_memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != _TRUE) )
++	{
++		return _FAIL;
++	}
++
++	pos = wpa_ie;
++
++	pos += 8;
++	left = wpa_ie_len - 8;
++
++
++	//group_cipher
++	if (left >= WPA_SELECTOR_LEN) {
++
++		*group_cipher = rtw_get_wpa_cipher_suite(pos);
++
++		pos += WPA_SELECTOR_LEN;
++		left -= WPA_SELECTOR_LEN;
++
++	}
++	else if (left > 0)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left));
++
++		return _FAIL;
++	}
++
++
++	//pairwise_cipher
++	if (left >= 2)
++	{
++                //count = le16_to_cpu(*(u16*)pos);
++		count = RTW_GET_LE16(pos);
++		pos += 2;
++		left -= 2;
++
++		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), "
++						"count %u left %u", __FUNCTION__, count, left));
++			return _FAIL;
++		}
++
++		for (i = 0; i < count; i++)
++		{
++			*pairwise_cipher |= rtw_get_wpa_cipher_suite(pos);
++
++			pos += WPA_SELECTOR_LEN;
++			left -= WPA_SELECTOR_LEN;
++		}
++
++	}
++	else if (left == 1)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)",   __FUNCTION__));
++		return _FAIL;
++	}
++
++
++	return ret;
++
++}
++
++int rtw_parse_wpa2_ie(u8* rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwise_cipher)
++{
++	int i, ret=_SUCCESS;
++	int left, count;
++	u8 *pos;
++
++	if (rsn_ie_len <= 0) {
++		/* No RSN IE - fail silently */
++		return _FAIL;
++	}
++
++
++	if ((*rsn_ie!= _WPA2_IE_ID_) || (*(rsn_ie+1) != (u8)(rsn_ie_len - 2)))
++	{
++		return _FAIL;
++	}
++
++	pos = rsn_ie;
++	pos += 4;
++	left = rsn_ie_len - 4;
++
++	//group_cipher
++	if (left >= RSN_SELECTOR_LEN) {
++
++		*group_cipher = rtw_get_wpa2_cipher_suite(pos);
++
++		pos += RSN_SELECTOR_LEN;
++		left -= RSN_SELECTOR_LEN;
++
++	} else if (left > 0) {
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie length mismatch, %u too much", __FUNCTION__, left));
++		return _FAIL;
++	}
++
++	//pairwise_cipher
++	if (left >= 2)
++	{
++	        //count = le16_to_cpu(*(u16*)pos);
++		count = RTW_GET_LE16(pos);
++		pos += 2;
++		left -= 2;
++
++		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie count botch (pairwise), "
++						 "count %u left %u", __FUNCTION__, count, left));
++			return _FAIL;
++		}
++
++		for (i = 0; i < count; i++)
++		{
++			*pairwise_cipher |= rtw_get_wpa2_cipher_suite(pos);
++
++			pos += RSN_SELECTOR_LEN;
++			left -= RSN_SELECTOR_LEN;
++		}
++
++	}
++	else if (left == 1)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s: ie too short (for key mgmt)",  __FUNCTION__));
++
++		return _FAIL;
++	}
++
++
++	return ret;
++
++}
++
++int rtw_get_sec_ie(u8 *in_ie,uint in_len,u8 *rsn_ie,u16 *rsn_len,u8 *wpa_ie,u16 *wpa_len)
++{
++	u8 authmode, sec_idx, i;
++	u8 wpa_oui[4]={0x0,0x50,0xf2,0x01};
++	uint 	cnt;
++
++_func_enter_;
++
++	//Search required WPA or WPA2 IE and copy to sec_ie[ ]
++
++	cnt = (_TIMESTAMP_ + _BEACON_ITERVAL_ + _CAPABILITY_);
++
++	sec_idx=0;
++
++	while(cnt<in_len)
++	{
++		authmode=in_ie[cnt];
++
++		if((authmode==_WPA_IE_ID_)&&(_rtw_memcmp(&in_ie[cnt+2], &wpa_oui[0],4)==_TRUE))
++		{
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_get_wpa_ie: sec_idx=%d in_ie[cnt+1]+2=%d\n",sec_idx,in_ie[cnt+1]+2));
++
++				_rtw_memcpy(wpa_ie, &in_ie[cnt],in_ie[cnt+1]+2);
++
++				for(i=0;i<(in_ie[cnt+1]+2);i=i+8){
++					RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n %2x,%2x,%2x,%2x,%2x,%2x,%2x,%2x\n",wpa_ie[i],wpa_ie[i+1],wpa_ie[i+2],wpa_ie[i+3],wpa_ie[i+4],wpa_ie[i+5],wpa_ie[i+6],wpa_ie[i+7]));
++				}
++
++				*wpa_len=in_ie[cnt+1]+2;
++				cnt+=in_ie[cnt+1]+2;  //get next
++		}
++		else
++		{
++			if(authmode==_WPA2_IE_ID_)
++			{
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n get_rsn_ie: sec_idx=%d in_ie[cnt+1]+2=%d\n",sec_idx,in_ie[cnt+1]+2));
++
++				_rtw_memcpy(rsn_ie, &in_ie[cnt],in_ie[cnt+1]+2);
++
++				for(i=0;i<(in_ie[cnt+1]+2);i=i+8){
++					RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n %2x,%2x,%2x,%2x,%2x,%2x,%2x,%2x\n",rsn_ie[i],rsn_ie[i+1],rsn_ie[i+2],rsn_ie[i+3],rsn_ie[i+4],rsn_ie[i+5],rsn_ie[i+6],rsn_ie[i+7]));
++				}
++
++				*rsn_len=in_ie[cnt+1]+2;
++				cnt+=in_ie[cnt+1]+2;  //get next
++			}
++			else
++			{
++				cnt+=in_ie[cnt+1]+2;   //get next
++			}
++		}
++
++	}
++
++_func_exit_;
++
++	return (*rsn_len+*wpa_len);
++
++}
++
++u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen)
++{
++	u8 match = _FALSE;
++	u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
++
++	if(ie_ptr == NULL) return match;
++
++	eid = ie_ptr[0];
++
++	if((eid==_WPA_IE_ID_)&&(_rtw_memcmp(&ie_ptr[2], wps_oui, 4)==_TRUE))
++	{
++		//printk("==> found WPS_IE.....\n");
++		*wps_ielen = ie_ptr[1]+2;
++		match=_TRUE;
++	}
++	return match;
++}
++
++/**
++ * rtw_get_wps_ie - Search WPS IE from a series of IEs
++ * @in_ie: Address of IEs to search
++ * @in_len: Length limit from in_ie
++ * @wps_ie: If not NULL and WPS IE is found, WPS IE will be copied to the buf starting from wps_ie
++ * @wps_ielen: If not NULL and WPS IE is found, will set to the length of the entire WPS IE
++ *
++ * Returns: The address of the WPS IE found, or NULL
++ */
++u8 *rtw_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen)
++{
++	uint cnt;
++	u8 *wpsie_ptr=NULL;
++	u8 eid, wps_oui[4]={0x0,0x50,0xf2,0x04};
++
++	if(wps_ielen)
++		*wps_ielen = 0;
++
++	if(!in_ie || in_len<=0)
++		return wpsie_ptr;
++
++	cnt = 0;
++
++	while(cnt<in_len)
++	{
++		eid = in_ie[cnt];
++
++		if((eid==_WPA_IE_ID_)&&(_rtw_memcmp(&in_ie[cnt+2], wps_oui, 4)==_TRUE))
++		{
++			wpsie_ptr = &in_ie[cnt];
++
++			if(wps_ie)
++				_rtw_memcpy(wps_ie, &in_ie[cnt], in_ie[cnt+1]+2);
++
++			if(wps_ielen)
++				*wps_ielen = in_ie[cnt+1]+2;
++
++			cnt+=in_ie[cnt+1]+2;
++
++			break;
++		}
++		else
++		{
++			cnt+=in_ie[cnt+1]+2; //goto next
++		}
++
++	}
++
++	return wpsie_ptr;
++}
++
++/**
++ * rtw_get_wps_attr - Search a specific WPS attribute from a given WPS IE
++ * @wps_ie: Address of WPS IE to search
++ * @wps_ielen: Length limit from wps_ie
++ * @target_attr_id: The attribute ID of WPS attribute to search
++ * @buf_attr: If not NULL and the WPS attribute is found, WPS attribute will be copied to the buf starting from buf_attr
++ * @len_attr: If not NULL and the WPS attribute is found, will set to the length of the entire WPS attribute
++ *
++ * Returns: the address of the specific WPS attribute found, or NULL
++ */
++u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_attr, u32 *len_attr)
++{
++	u8 *attr_ptr = NULL;
++	u8 * target_attr_ptr = NULL;
++	u8 wps_oui[4]={0x00,0x50,0xF2,0x04};
++
++	if(len_attr)
++		*len_attr = 0;
++
++	if ( ( wps_ie[0] != _VENDOR_SPECIFIC_IE_ ) ||
++		( _rtw_memcmp( wps_ie + 2, wps_oui , 4 ) != _TRUE ) )
++	{
++		return attr_ptr;
++	}
++
++	// 6 = 1(Element ID) + 1(Length) + 4(WPS OUI)
++	attr_ptr = wps_ie + 6; //goto first attr
++
++	while(attr_ptr - wps_ie < wps_ielen)
++	{
++		// 4 = 2(Attribute ID) + 2(Length)
++		u16 attr_id = RTW_GET_BE16(attr_ptr);
++		u16 attr_data_len = RTW_GET_BE16(attr_ptr + 2);
++		u16 attr_len = attr_data_len + 4;
++
++		//DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __FUNCTION__, attr_ptr, attr_id, attr_data_len);
++		if( attr_id == target_attr_id )
++		{
++			target_attr_ptr = attr_ptr;
++
++			if(buf_attr)
++				_rtw_memcpy(buf_attr, attr_ptr, attr_len);
++
++			if(len_attr)
++				*len_attr = attr_len;
++
++			break;
++		}
++		else
++		{
++			attr_ptr += attr_len; //goto next
++		}
++
++	}
++
++	return target_attr_ptr;
++}
++
++/**
++ * rtw_get_wps_attr_content - Search a specific WPS attribute content from a given WPS IE
++ * @wps_ie: Address of WPS IE to search
++ * @wps_ielen: Length limit from wps_ie
++ * @target_attr_id: The attribute ID of WPS attribute to search
++ * @buf_content: If not NULL and the WPS attribute is found, WPS attribute content will be copied to the buf starting from buf_content
++ * @len_content: If not NULL and the WPS attribute is found, will set to the length of the WPS attribute content
++ *
++ * Returns: the address of the specific WPS attribute content found, or NULL
++ */
++u8 *rtw_get_wps_attr_content(u8 *wps_ie, uint wps_ielen, u16 target_attr_id ,u8 *buf_content, uint *len_content)
++{
++	u8 *attr_ptr;
++	u32 attr_len;
++
++	if(len_content)
++		*len_content = 0;
++
++	attr_ptr = rtw_get_wps_attr(wps_ie, wps_ielen, target_attr_id, NULL, &attr_len);
++
++	if(attr_ptr && attr_len)
++	{
++		if(buf_content)
++			_rtw_memcpy(buf_content, attr_ptr+4, attr_len-4);
++
++		if(len_content)
++			*len_content = attr_len-4;
++
++		return attr_ptr+4;
++	}
++
++	return NULL;
++}
++
++static int rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen,
++					    struct rtw_ieee802_11_elems *elems,
++					    int show_errors)
++{
++	unsigned int oui;
++
++	/* first 3 bytes in vendor specific information element are the IEEE
++	 * OUI of the vendor. The following byte is used a vendor specific
++	 * sub-type. */
++	if (elen < 4) {
++		if (show_errors) {
++			DBG_871X("short vendor specific "
++				   "information element ignored (len=%lu)\n",
++				   (unsigned long) elen);
++		}
++		return -1;
++	}
++
++	oui = RTW_GET_BE24(pos);
++	switch (oui) {
++	case OUI_MICROSOFT:
++		/* Microsoft/Wi-Fi information elements are further typed and
++		 * subtyped */
++		switch (pos[3]) {
++		case 1:
++			/* Microsoft OUI (00:50:F2) with OUI Type 1:
++			 * real WPA information element */
++			elems->wpa_ie = pos;
++			elems->wpa_ie_len = elen;
++			break;
++		case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
++			if (elen < 5) {
++				DBG_871X("short WME "
++					   "information element ignored "
++					   "(len=%lu)\n",
++					   (unsigned long) elen);
++				return -1;
++			}
++			switch (pos[4]) {
++			case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
++			case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
++				elems->wme = pos;
++				elems->wme_len = elen;
++				break;
++			case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
++				elems->wme_tspec = pos;
++				elems->wme_tspec_len = elen;
++				break;
++			default:
++				DBG_871X("unknown WME "
++					   "information element ignored "
++					   "(subtype=%d len=%lu)\n",
++					   pos[4], (unsigned long) elen);
++				return -1;
++			}
++			break;
++		case 4:
++			/* Wi-Fi Protected Setup (WPS) IE */
++			elems->wps_ie = pos;
++			elems->wps_ie_len = elen;
++			break;
++		default:
++			DBG_871X("Unknown Microsoft "
++				   "information element ignored "
++				   "(type=%d len=%lu)\n",
++				   pos[3], (unsigned long) elen);
++			return -1;
++		}
++		break;
++
++	case OUI_BROADCOM:
++		switch (pos[3]) {
++		case VENDOR_HT_CAPAB_OUI_TYPE:
++			elems->vendor_ht_cap = pos;
++			elems->vendor_ht_cap_len = elen;
++			break;
++		default:
++			DBG_871X("Unknown Broadcom "
++				   "information element ignored "
++				   "(type=%d len=%lu)\n",
++				   pos[3], (unsigned long) elen);
++			return -1;
++		}
++		break;
++
++	default:
++		DBG_871X("unknown vendor specific information "
++			   "element ignored (vendor OUI %02x:%02x:%02x "
++			   "len=%lu)\n",
++			   pos[0], pos[1], pos[2], (unsigned long) elen);
++		return -1;
++	}
++
++	return 0;
++
++}
++
++/**
++ * ieee802_11_parse_elems - Parse information elements in management frames
++ * @start: Pointer to the start of IEs
++ * @len: Length of IE buffer in octets
++ * @elems: Data structure for parsed elements
++ * @show_errors: Whether to show parsing errors in debug log
++ * Returns: Parsing result
++ */
++ParseRes rtw_ieee802_11_parse_elems(u8 *start, uint len,
++				struct rtw_ieee802_11_elems *elems,
++				int show_errors)
++{
++	uint left = len;
++	u8 *pos = start;
++	int unknown = 0;
++
++	_rtw_memset(elems, 0, sizeof(*elems));
++
++	while (left >= 2) {
++		u8 id, elen;
++
++		id = *pos++;
++		elen = *pos++;
++		left -= 2;
++
++		if (elen > left) {
++			if (show_errors) {
++				DBG_871X("IEEE 802.11 element "
++					   "parse failed (id=%d elen=%d "
++					   "left=%lu)\n",
++					   id, elen, (unsigned long) left);
++			}
++			return ParseFailed;
++		}
++
++		switch (id) {
++		case WLAN_EID_SSID:
++			elems->ssid = pos;
++			elems->ssid_len = elen;
++			break;
++		case WLAN_EID_SUPP_RATES:
++			elems->supp_rates = pos;
++			elems->supp_rates_len = elen;
++			break;
++		case WLAN_EID_FH_PARAMS:
++			elems->fh_params = pos;
++			elems->fh_params_len = elen;
++			break;
++		case WLAN_EID_DS_PARAMS:
++			elems->ds_params = pos;
++			elems->ds_params_len = elen;
++			break;
++		case WLAN_EID_CF_PARAMS:
++			elems->cf_params = pos;
++			elems->cf_params_len = elen;
++			break;
++		case WLAN_EID_TIM:
++			elems->tim = pos;
++			elems->tim_len = elen;
++			break;
++		case WLAN_EID_IBSS_PARAMS:
++			elems->ibss_params = pos;
++			elems->ibss_params_len = elen;
++			break;
++		case WLAN_EID_CHALLENGE:
++			elems->challenge = pos;
++			elems->challenge_len = elen;
++			break;
++		case WLAN_EID_ERP_INFO:
++			elems->erp_info = pos;
++			elems->erp_info_len = elen;
++			break;
++		case WLAN_EID_EXT_SUPP_RATES:
++			elems->ext_supp_rates = pos;
++			elems->ext_supp_rates_len = elen;
++			break;
++		case WLAN_EID_VENDOR_SPECIFIC:
++			if (rtw_ieee802_11_parse_vendor_specific(pos, elen,
++							     elems,
++							     show_errors))
++				unknown++;
++			break;
++		case WLAN_EID_RSN:
++			elems->rsn_ie = pos;
++			elems->rsn_ie_len = elen;
++			break;
++		case WLAN_EID_PWR_CAPABILITY:
++			elems->power_cap = pos;
++			elems->power_cap_len = elen;
++			break;
++		case WLAN_EID_SUPPORTED_CHANNELS:
++			elems->supp_channels = pos;
++			elems->supp_channels_len = elen;
++			break;
++		case WLAN_EID_MOBILITY_DOMAIN:
++			elems->mdie = pos;
++			elems->mdie_len = elen;
++			break;
++		case WLAN_EID_FAST_BSS_TRANSITION:
++			elems->ftie = pos;
++			elems->ftie_len = elen;
++			break;
++		case WLAN_EID_TIMEOUT_INTERVAL:
++			elems->timeout_int = pos;
++			elems->timeout_int_len = elen;
++			break;
++		case WLAN_EID_HT_CAP:
++			elems->ht_capabilities = pos;
++			elems->ht_capabilities_len = elen;
++			break;
++		case WLAN_EID_HT_OPERATION:
++			elems->ht_operation = pos;
++			elems->ht_operation_len = elen;
++			break;
++		default:
++			unknown++;
++			if (!show_errors)
++				break;
++			DBG_871X("IEEE 802.11 element parse "
++				   "ignored unknown element (id=%d elen=%d)\n",
++				   id, elen);
++			break;
++		}
++
++		left -= elen;
++		pos += elen;
++	}
++
++	if (left)
++		return ParseFailed;
++
++	return unknown ? ParseUnknown : ParseOK;
++
++}
++
++static u8 key_char2num(u8 ch);
++static u8 key_char2num(u8 ch)
++{
++    if((ch>='0')&&(ch<='9'))
++        return ch - '0';
++    else if ((ch>='a')&&(ch<='f'))
++        return ch - 'a' + 10;
++    else if ((ch>='A')&&(ch<='F'))
++        return ch - 'A' + 10;
++    else
++	 return 0xff;
++}
++
++u8 str_2char2num(u8 hch, u8 lch);
++u8 str_2char2num(u8 hch, u8 lch)
++{
++    return ((key_char2num(hch) * 10 ) + key_char2num(lch));
++}
++
++u8 key_2char2num(u8 hch, u8 lch);
++u8 key_2char2num(u8 hch, u8 lch)
++{
++    return ((key_char2num(hch) << 4) | key_char2num(lch));
++}
++
++u8 convert_ip_addr(u8 hch, u8 mch, u8 lch)
++{
++    return ((key_char2num(hch) * 100) + (key_char2num(mch) * 10 ) + key_char2num(lch));
++}
++
++extern char* rtw_initmac;
++void rtw_macaddr_cfg(u8 *mac_addr)
++{
++	u8 mac[ETH_ALEN];
++	if(mac_addr == NULL)	return;
++
++	if ( rtw_initmac )
++	{	//	Users specify the mac address
++		int jj,kk;
++
++		for( jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3 )
++		{
++			mac[jj] = key_2char2num(rtw_initmac[kk], rtw_initmac[kk+ 1]);
++		}
++		_rtw_memcpy(mac_addr, mac, ETH_ALEN);
++	}
++	else
++	{	//	Use the mac address stored in the Efuse
++		_rtw_memcpy(mac, mac_addr, ETH_ALEN);
++	}
++
++	if (((mac[0]==0xff) &&(mac[1]==0xff) && (mac[2]==0xff) &&
++	     (mac[3]==0xff) && (mac[4]==0xff) &&(mac[5]==0xff)) ||
++	    ((mac[0]==0x0) && (mac[1]==0x0) && (mac[2]==0x0) &&
++	     (mac[3]==0x0) && (mac[4]==0x0) &&(mac[5]==0x0)))
++	{
++		mac[0] = 0x00;
++		mac[1] = 0xe0;
++		mac[2] = 0x4c;
++		mac[3] = 0x87;
++		mac[4] = 0x00;
++		mac[5] = 0x00;
++		// use default mac addresss
++		_rtw_memcpy(mac_addr, mac, ETH_ALEN);
++		DBG_871X("MAC Address from efuse error, assign default one !!!\n");
++	}
++
++	DBG_871X("rtw_macaddr_cfg MAC Address  = "MAC_FMT"\n", MAC_ARG(mac_addr));
++}
++
++void dump_ies(u8 *buf, u32 buf_len) {
++	u8* pos = (u8*)buf;
++	u8 id, len;
++
++	while(pos-buf<=buf_len){
++		id = *pos;
++		len = *(pos+1);
++
++		DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len);
++		#ifdef CONFIG_P2P
++		dump_p2p_ie(pos, len);
++		#endif
++		dump_wps_ie(pos, len);
++
++		pos+=(2+len);
++	}
++}
++
++void dump_wps_ie(u8 *ie, u32 ie_len) {
++	u8* pos = (u8*)ie;
++	u16 id;
++	u16 len;
++
++	u8 *wps_ie;
++	uint wps_ielen;
++
++	wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen);
++	if(wps_ie != ie || wps_ielen == 0)
++		return;
++
++	pos+=6;
++	while(pos-ie < ie_len){
++		id = RTW_GET_BE16(pos);
++		len = RTW_GET_BE16(pos + 2);
++
++		DBG_871X("%s ID:0x%04x, LEN:%u\n", __FUNCTION__, id, len);
++
++		pos+=(4+len);
++	}
++}
++
++#ifdef CONFIG_P2P
++/**
++ * rtw_get_p2p_merged_len - Get merged ie length from muitiple p2p ies.
++ * @in_ie: Pointer of the first p2p ie
++ * @in_len: Total len of muiltiple p2p ies
++ * Returns: Length of merged p2p ie length
++ */
++u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len)
++{
++	PNDIS_802_11_VARIABLE_IEs	pIE;
++	u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 };
++	int i=0;
++	int j=0, len=0;
++
++	while( i < in_len)
++	{
++		pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i);
++
++		if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) )
++		{
++			len += pIE->Length-4; // 4 is P2P OUI length, don't count it in this loop
++		}
++
++		i += (pIE->Length + 2);
++	}
++
++	return len + 4;	// Append P2P OUI length at last.
++}
++
++/**
++ * rtw_p2p_merge_ies - Merge muitiple p2p ies into one
++ * @in_ie: Pointer of the first p2p ie
++ * @in_len: Total len of muiltiple p2p ies
++ * @merge_ie: Pointer of merged ie
++ * Returns: Length of merged p2p ie
++ */
++int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie)
++{
++	PNDIS_802_11_VARIABLE_IEs	pIE;
++	u8 len = 0;
++	u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 };
++	u8 ELOUI[6] = { 0xDD, 0x00, 0x50, 0x6f, 0x9a, 0x09 };	//EID;Len;OUI, Len would copy at the end of function
++	int i=0;
++
++	if( merge_ie != NULL)
++	{
++		//Set first P2P OUI
++		_rtw_memcpy(merge_ie, ELOUI, 6);
++		merge_ie += 6;
++
++		while( i < in_len)
++		{
++			pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i);
++
++			// Take out the rest of P2P OUIs
++			if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) )
++			{
++				_rtw_memcpy( merge_ie, pIE->data +4, pIE->Length -4);
++				len += pIE->Length-4;
++				merge_ie += pIE->Length-4;
++			}
++
++			i += (pIE->Length + 2);
++		}
++
++		return len + 4;	// 4 is for P2P OUI
++
++	}
++
++	return 0;
++}
++
++void dump_p2p_ie(u8 *ie, u32 ie_len) {
++	u8* pos = (u8*)ie;
++	u8 id;
++	u16 len;
++
++	u8 *p2p_ie;
++	uint p2p_ielen;
++
++	p2p_ie = rtw_get_p2p_ie(ie, ie_len, NULL, &p2p_ielen);
++	if(p2p_ie != ie || p2p_ielen == 0)
++		return;
++
++	pos+=6;
++	while(pos-ie < ie_len){
++		id = *pos;
++		len = RTW_GET_LE16(pos+1);
++
++		DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len);
++
++		pos+=(3+len);
++	}
++}
++
++/**
++ * rtw_get_p2p_ie - Search P2P IE from a series of IEs
++ * @in_ie: Address of IEs to search
++ * @in_len: Length limit from in_ie
++ * @p2p_ie: If not NULL and P2P IE is found, P2P IE will be copied to the buf starting from p2p_ie
++ * @p2p_ielen: If not NULL and P2P IE is found, will set to the length of the entire P2P IE
++ *
++ * Returns: The address of the P2P IE found, or NULL
++ */
++u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen)
++{
++	uint cnt = 0;
++	u8 *p2p_ie_ptr;
++	u8 eid, p2p_oui[4]={0x50,0x6F,0x9A,0x09};
++
++	if ( p2p_ielen != NULL )
++		*p2p_ielen = 0;
++
++	while(cnt<in_len)
++	{
++		eid = in_ie[cnt];
++		if ((in_len < 0) || (cnt > MAX_IE_SZ)) {
++#ifdef PLATFORM_LINUX
++			dump_stack();
++#endif
++			return NULL;
++		}
++		if( ( eid == _VENDOR_SPECIFIC_IE_ ) && ( _rtw_memcmp( &in_ie[cnt+2], p2p_oui, 4) == _TRUE ) )
++		{
++			p2p_ie_ptr = in_ie + cnt;
++
++			if ( p2p_ie != NULL )
++			{
++				_rtw_memcpy( p2p_ie, &in_ie[ cnt ], in_ie[ cnt + 1 ] + 2 );
++			}
++
++			if ( p2p_ielen != NULL )
++			{
++				*p2p_ielen = in_ie[ cnt + 1 ] + 2;
++			}
++
++			return p2p_ie_ptr;
++
++			break;
++		}
++		else
++		{
++			cnt += in_ie[ cnt + 1 ] +2; //goto next
++		}
++
++	}
++
++	return NULL;
++
++}
++
++/**
++ * rtw_get_p2p_attr - Search a specific P2P attribute from a given P2P IE
++ * @p2p_ie: Address of P2P IE to search
++ * @p2p_ielen: Length limit from p2p_ie
++ * @target_attr_id: The attribute ID of P2P attribute to search
++ * @buf_attr: If not NULL and the P2P attribute is found, P2P attribute will be copied to the buf starting from buf_attr
++ * @len_attr: If not NULL and the P2P attribute is found, will set to the length of the entire P2P attribute
++ *
++ * Returns: the address of the specific WPS attribute found, or NULL
++ */
++u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_attr, u32 *len_attr)
++{
++	u8 *attr_ptr = NULL;
++	u8 *target_attr_ptr = NULL;
++	u8 p2p_oui[4]={0x50,0x6F,0x9A,0x09};
++
++	if(len_attr)
++		*len_attr = 0;
++
++	if ( !p2p_ie || ( p2p_ie[0] != _VENDOR_SPECIFIC_IE_ ) ||
++		( _rtw_memcmp( p2p_ie + 2, p2p_oui , 4 ) != _TRUE ) )
++	{
++		return attr_ptr;
++	}
++
++	// 6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type)
++	attr_ptr = p2p_ie + 6; //goto first attr
++
++	while(attr_ptr - p2p_ie < p2p_ielen)
++	{
++		// 3 = 1(Attribute ID) + 2(Length)
++		u8 attr_id = *attr_ptr;
++		u16 attr_data_len = RTW_GET_LE16(attr_ptr + 1);
++		u16 attr_len = attr_data_len + 3;
++
++		//DBG_871X("%s attr_ptr:%p, id:%u, length:%u\n", __FUNCTION__, attr_ptr, attr_id, attr_data_len);
++		if( attr_id == target_attr_id )
++		{
++			target_attr_ptr = attr_ptr;
++
++			if(buf_attr)
++				_rtw_memcpy(buf_attr, attr_ptr, attr_len);
++
++			if(len_attr)
++				*len_attr = attr_len;
++
++			break;
++		}
++		else
++		{
++			attr_ptr += attr_len; //goto next
++		}
++
++	}
++
++	return target_attr_ptr;
++}
++
++/**
++ * rtw_get_p2p_attr_content - Search a specific P2P attribute content from a given P2P IE
++ * @p2p_ie: Address of P2P IE to search
++ * @p2p_ielen: Length limit from p2p_ie
++ * @target_attr_id: The attribute ID of P2P attribute to search
++ * @buf_content: If not NULL and the P2P attribute is found, P2P attribute content will be copied to the buf starting from buf_content
++ * @len_content: If not NULL and the P2P attribute is found, will set to the length of the P2P attribute content
++ *
++ * Returns: the address of the specific P2P attribute content found, or NULL
++ */
++u8 *rtw_get_p2p_attr_content(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id ,u8 *buf_content, uint *len_content)
++{
++	u8 *attr_ptr;
++	u32 attr_len;
++
++	if(len_content)
++		*len_content = 0;
++
++	attr_ptr = rtw_get_p2p_attr(p2p_ie, p2p_ielen, target_attr_id, NULL, &attr_len);
++
++	if(attr_ptr && attr_len)
++	{
++		if(buf_content)
++			_rtw_memcpy(buf_content, attr_ptr+3, attr_len-3);
++
++		if(len_content)
++			*len_content = attr_len-3;
++
++		return attr_ptr+3;
++	}
++
++	return NULL;
++}
++
++u32 rtw_set_p2p_attr_content(u8 *pbuf, u8 attr_id, u16 attr_len, u8 *pdata_attr)
++{
++	u32 a_len;
++
++	*pbuf = attr_id;
++
++	//*(u16*)(pbuf + 1) = cpu_to_le16(attr_len);
++	RTW_PUT_LE16(pbuf + 1, attr_len);
++
++	if(pdata_attr)
++		_rtw_memcpy(pbuf + 3, pdata_attr, attr_len);
++
++	a_len = attr_len + 3;
++
++	return a_len;
++}
++
++static uint rtw_p2p_attr_remove(u8 *ie, uint ielen_ori, u8 attr_id)
++{
++	u8 *target_attr;
++	u32 target_attr_len;
++	uint ielen = ielen_ori;
++	int index=0;
++
++	while(1) {
++		target_attr=rtw_get_p2p_attr(ie, ielen, attr_id, NULL, &target_attr_len);
++		if(target_attr && target_attr_len)
++		{
++			u8 *next_attr = target_attr+target_attr_len;
++			uint remain_len = ielen-(next_attr-ie);
++			//dump_ies(ie, ielen);
++			#if 0
++			DBG_871X("[%d] ie:%p, ielen:%u\n"
++				"target_attr:%p, target_attr_len:%u\n"
++				"next_attr:%p, remain_len:%u\n"
++				, index++
++				, ie, ielen
++				, target_attr, target_attr_len
++				, next_attr, remain_len
++			);
++			#endif
++
++			_rtw_memset(target_attr, 0, target_attr_len);
++			_rtw_memcpy(target_attr, next_attr, remain_len);
++			_rtw_memset(target_attr+remain_len, 0, target_attr_len);
++			*(ie+1) -= target_attr_len;
++			ielen-=target_attr_len;
++		}
++		else
++		{
++			//if(index>0)
++			//	dump_ies(ie, ielen);
++			break;
++		}
++	}
++
++	return ielen;
++}
++
++void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id)
++{
++	u8 *p2p_ie;
++	uint p2p_ielen, p2p_ielen_ori;
++	int cnt;
++
++	if( (p2p_ie=rtw_get_p2p_ie(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_, NULL, &p2p_ielen_ori)) )
++	{
++		#if 0
++		if(rtw_get_p2p_attr(p2p_ie, p2p_ielen_ori, attr_id, NULL, NULL)) {
++			DBG_871X("rtw_get_p2p_attr: GOT P2P_ATTR:%u!!!!!!!!\n", attr_id);
++			dump_ies(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_);
++		}
++		#endif
++
++		p2p_ielen=rtw_p2p_attr_remove(p2p_ie, p2p_ielen_ori, attr_id);
++		if(p2p_ielen != p2p_ielen_ori) {
++
++			u8 *next_ie_ori = p2p_ie+p2p_ielen_ori;
++			u8 *next_ie = p2p_ie+p2p_ielen;
++			uint remain_len = bss_ex->IELength-(next_ie_ori-bss_ex->IEs);
++
++			_rtw_memcpy(next_ie, next_ie_ori, remain_len);
++			_rtw_memset(next_ie+remain_len, 0, p2p_ielen_ori-p2p_ielen);
++			bss_ex->IELength -= p2p_ielen_ori-p2p_ielen;
++
++			#if 0
++			DBG_871X("remove P2P_ATTR:%u!\n", attr_id);
++			dump_ies(bss_ex->IEs+_FIXED_IE_LENGTH_, bss_ex->IELength-_FIXED_IE_LENGTH_);
++			#endif
++		}
++	}
++}
++
++#endif //CONFIG_P2P
++
++#ifdef CONFIG_WFD
++int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
++{
++	int match;
++	uint cnt = 0;
++	u8 eid, wfd_oui[4]={0x50,0x6F,0x9A,0x0A};
++
++
++	match=_FALSE;
++
++	if ( in_len < 0 )
++	{
++		return match;
++	}
++
++	while(cnt<in_len)
++	{
++		eid = in_ie[cnt];
++
++		if( ( eid == _VENDOR_SPECIFIC_IE_ ) && ( _rtw_memcmp( &in_ie[cnt+2], wfd_oui, 4) == _TRUE ) )
++		{
++			if ( wfd_ie != NULL )
++			{
++				_rtw_memcpy( wfd_ie, &in_ie[ cnt ], in_ie[ cnt + 1 ] + 2 );
++
++			}
++			else
++			{
++				if ( wfd_ielen != NULL )
++				{
++					*wfd_ielen = 0;
++				}
++			}
++
++			if ( wfd_ielen != NULL )
++			{
++				*wfd_ielen = in_ie[ cnt + 1 ] + 2;
++			}
++
++			cnt += in_ie[ cnt + 1 ] + 2;
++
++			match = _TRUE;
++			break;
++		}
++		else
++		{
++			cnt += in_ie[ cnt + 1 ] +2; //goto next
++		}
++
++	}
++
++	if ( match == _TRUE )
++	{
++		match = cnt;
++	}
++
++	return match;
++
++}
++
++//	attr_content: The output buffer, contains the "body field" of WFD attribute.
++//	attr_contentlen: The data length of the "body field" of WFD attribute.
++int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen)
++{
++	int match;
++	uint cnt = 0;
++	u8 attr_id, wfd_oui[4]={0x50,0x6F,0x9A,0x0A};
++
++
++	match=_FALSE;
++
++	if ( ( wfd_ie[ 0 ] != _VENDOR_SPECIFIC_IE_ ) ||
++		( _rtw_memcmp( wfd_ie + 2, wfd_oui , 4 ) != _TRUE ) )
++	{
++		return( match );
++	}
++
++	//	1 ( WFD IE ) + 1 ( Length ) + 3 ( OUI ) + 1 ( OUI Type )
++	cnt = 6;
++	while( cnt < wfd_ielen )
++	{
++		u16 attrlen = RTW_GET_BE16(wfd_ie + cnt + 1);
++
++		attr_id = wfd_ie[cnt];
++		if( attr_id == target_attr_id )
++		{
++			//	3 -> 1 byte for attribute ID field, 2 bytes for length field
++			if(attr_content)
++				_rtw_memcpy( attr_content, &wfd_ie[ cnt + 3 ], attrlen );
++
++			if(attr_contentlen)
++				*attr_contentlen = attrlen;
++
++			cnt += attrlen + 3;
++
++			match = _TRUE;
++			break;
++		}
++		else
++		{
++			cnt += attrlen + 3; //goto next
++		}
++
++	}
++
++	return match;
++
++}
++#endif // CONFIG_WFD
++
++//Baron adds to avoid FreeBSD warning
++int ieee80211_is_empty_essid(const char *essid, int essid_len)
++{
++	/* Single white space is for Linksys APs */
++	if (essid_len == 1 && essid[0] == ' ')
++		return 1;
++
++	/* Otherwise, if the entire essid is 0, we assume it is hidden */
++	while (essid_len) {
++		essid_len--;
++		if (essid[essid_len] != '\0')
++			return 0;
++	}
++
++	return 1;
++}
++
++int ieee80211_get_hdrlen(u16 fc)
++{
++	int hdrlen = 24;
++
++	switch (WLAN_FC_GET_TYPE(fc)) {
++	case RTW_IEEE80211_FTYPE_DATA:
++		if (fc & RTW_IEEE80211_STYPE_QOS_DATA)
++			hdrlen += 2;
++		if ((fc & RTW_IEEE80211_FCTL_FROMDS) && (fc & RTW_IEEE80211_FCTL_TODS))
++			hdrlen += 6; /* Addr4 */
++		break;
++	case RTW_IEEE80211_FTYPE_CTL:
++		switch (WLAN_FC_GET_STYPE(fc)) {
++		case RTW_IEEE80211_STYPE_CTS:
++		case RTW_IEEE80211_STYPE_ACK:
++			hdrlen = 10;
++			break;
++		default:
++			hdrlen = 16;
++			break;
++		}
++		break;
++	}
++
++	return hdrlen;
++}
++
++//show MCS rate, unit: 100Kbps
++u16 rtw_mcs_rate(u8 rf_type, u8 bw_40MHz, u8 short_GI_20, u8 short_GI_40, unsigned char * MCS_rate)
++{
++	u16 max_rate = 0;
++
++	if(rf_type == RF_1T1R)
++	{
++		if(MCS_rate[0] & BIT(7))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):((short_GI_20)?722:650);
++		else if(MCS_rate[0] & BIT(6))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):((short_GI_20)?650:585);
++		else if(MCS_rate[0] & BIT(5))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
++		else if(MCS_rate[0] & BIT(4))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
++		else if(MCS_rate[0] & BIT(3))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
++		else if(MCS_rate[0] & BIT(2))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):((short_GI_20)?217:195);
++		else if(MCS_rate[0] & BIT(1))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
++		else if(MCS_rate[0] & BIT(0))
++			max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):((short_GI_20)?72:65);
++	}
++	else
++	{
++		if(MCS_rate[1])
++		{
++			if(MCS_rate[1] & BIT(7))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?3000:2700):((short_GI_20)?1444:1300);
++			else if(MCS_rate[1] & BIT(6))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?2700:2430):((short_GI_20)?1300:1170);
++			else if(MCS_rate[1] & BIT(5))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?2400:2160):((short_GI_20)?1156:1040);
++			else if(MCS_rate[1] & BIT(4))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?1800:1620):((short_GI_20)?867:780);
++			else if(MCS_rate[1] & BIT(3))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
++			else if(MCS_rate[1] & BIT(2))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
++			else if(MCS_rate[1] & BIT(1))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
++			else if(MCS_rate[1] & BIT(0))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
++		}
++		else
++		{
++			if(MCS_rate[0] & BIT(7))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?1500:1350):((short_GI_20)?722:650);
++			else if(MCS_rate[0] & BIT(6))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?1350:1215):((short_GI_20)?650:585);
++			else if(MCS_rate[0] & BIT(5))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?1200:1080):((short_GI_20)?578:520);
++			else if(MCS_rate[0] & BIT(4))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?900:810):((short_GI_20)?433:390);
++			else if(MCS_rate[0] & BIT(3))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?600:540):((short_GI_20)?289:260);
++			else if(MCS_rate[0] & BIT(2))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?450:405):((short_GI_20)?217:195);
++			else if(MCS_rate[0] & BIT(1))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?300:270):((short_GI_20)?144:130);
++			else if(MCS_rate[0] & BIT(0))
++				max_rate = (bw_40MHz) ? ((short_GI_40)?150:135):((short_GI_20)?72:65);
++		}
++	}
++	return max_rate;
++}
++
++int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8* category, u8 *action)
++{
++	const u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr);
++	u16 fc;
++	u8 c, a;
++
++	fc = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)frame)->frame_ctl);
++
++	if ((fc & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
++		!= (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
++	)
++	{
++		return _FALSE;
++	}
++
++	c = frame_body[0];
++
++	switch(c) {
++	case RTW_WLAN_CATEGORY_P2P: /* vendor-specific */
++		break;
++	default:
++		a = frame_body[1];
++	}
++
++	if (category)
++		*category = c;
++	if (action)
++		*action = a;
++
++	return _TRUE;
++}
++
++static const char *_action_public_str[] = {
++	"ACT_PUB_BSSCOEXIST",
++	"ACT_PUB_DSE_ENABLE",
++	"ACT_PUB_DSE_DEENABLE",
++	"ACT_PUB_DSE_REG_LOCATION",
++	"ACT_PUB_EXT_CHL_SWITCH",
++	"ACT_PUB_DSE_MSR_REQ",
++	"ACT_PUB_DSE_MSR_RPRT",
++	"ACT_PUB_MP",
++	"ACT_PUB_DSE_PWR_CONSTRAINT",
++	"ACT_PUB_VENDOR",
++	"ACT_PUB_GAS_INITIAL_REQ",
++	"ACT_PUB_GAS_INITIAL_RSP",
++	"ACT_PUB_GAS_COMEBACK_REQ",
++	"ACT_PUB_GAS_COMEBACK_RSP",
++	"ACT_PUB_TDLS_DISCOVERY_RSP",
++	"ACT_PUB_LOCATION_TRACK",
++	"ACT_PUB_RSVD",
++};
++
++const char *action_public_str(u8 action)
++{
++	action = (action >= ACT_PUBLIC_MAX) ? ACT_PUBLIC_MAX : action;
++	return _action_public_str[action];
++}
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_io.c
+@@ -0,0 +1,462 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++/*
++
++The purpose of rtw_io.c
++
++a. provides the API
++
++b. provides the protocol engine
++
++c. provides the software interface between caller and the hardware interface
++
++
++Compiler Flag Option:
++
++1. CONFIG_SDIO_HCI:
++    a. USE_SYNC_IRP:  Only sync operations are provided.
++    b. USE_ASYNC_IRP:Both sync/async operations are provided.
++
++2. CONFIG_USB_HCI:
++   a. USE_ASYNC_IRP: Both sync/async operations are provided.
++
++3. CONFIG_CFIO_HCI:
++   b. USE_SYNC_IRP: Only sync operations are provided.
++
++
++Only sync read/rtw_write_mem operations are provided.
++
++jackson at realtek.com.tw
++
++*/
++
++#define _RTW_IO_C_
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <rtw_io.h>
++#include <osdep_intf.h>
++
++#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
++#error "Shall be Linux or Windows, but not both!\n"
++#endif
++
++#ifdef CONFIG_SDIO_HCI
++#include <sdio_ops.h>
++#endif
++
++#ifdef CONFIG_USB_HCI
++#include <usb_ops.h>
++#endif
++
++#ifdef CONFIG_PCI_HCI
++#include <pci_ops.h>
++#endif
++
++
++u8 _rtw_read8(_adapter *adapter, u32 addr)
++{
++	u8 r_val;
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
++	_func_enter_;
++	_read8 = pintfhdl->io_ops._read8;
++
++	r_val = _read8(pintfhdl, addr);
++	_func_exit_;
++	return r_val;
++}
++
++u16 _rtw_read16(_adapter *adapter, u32 addr)
++{
++	u16 r_val;
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	u16 	(*_read16)(struct intf_hdl *pintfhdl, u32 addr);
++	_func_enter_;
++	_read16 = pintfhdl->io_ops._read16;
++
++	r_val = _read16(pintfhdl, addr);
++	_func_exit_;
++	return r_val;
++}
++
++u32 _rtw_read32(_adapter *adapter, u32 addr)
++{
++	u32 r_val;
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	u32 	(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
++	_func_enter_;
++	_read32 = pintfhdl->io_ops._read32;
++
++	r_val = _read32(pintfhdl, addr);
++	_func_exit_;
++	return r_val;
++
++}
++
++int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
++	int ret;
++	_func_enter_;
++	_write8 = pintfhdl->io_ops._write8;
++
++	ret = _write8(pintfhdl, addr, val);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
++	int ret;
++	_func_enter_;
++	_write16 = pintfhdl->io_ops._write16;
++
++	ret = _write16(pintfhdl, addr, val);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
++	int ret;
++	_func_enter_;
++	_write32 = pintfhdl->io_ops._write32;
++
++	ret = _write32(pintfhdl, addr, val);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++
++int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++        struct	intf_hdl	*pintfhdl = (struct intf_hdl*)(&(pio_priv->intf));
++	int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata);
++	int ret;
++	_func_enter_;
++	_writeN = pintfhdl->io_ops._writeN;
++
++	ret = _writeN(pintfhdl, addr,length,pdata);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
++	int ret;
++	_func_enter_;
++	_write8_async = pintfhdl->io_ops._write8_async;
++
++	ret = _write8_async(pintfhdl, addr, val);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
++	int ret;
++	_func_enter_;
++	_write16_async = pintfhdl->io_ops._write16_async;
++
++	ret = _write16_async(pintfhdl, addr, val);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
++{
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
++	int ret;
++	_func_enter_;
++	_write32_async = pintfhdl->io_ops._write32_async;
++
++	ret = _write32_async(pintfhdl, addr, val);
++	_func_exit_;
++
++	return RTW_STATUS_CODE(ret);
++}
++void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
++{
++	void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++
++	_func_enter_;
++
++	if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
++	{
++	     RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
++	     return;
++	}
++
++	_read_mem = pintfhdl->io_ops._read_mem;
++
++	_read_mem(pintfhdl, addr, cnt, pmem);
++
++	_func_exit_;
++
++}
++
++void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
++{
++	void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++
++	_func_enter_;
++
++	_write_mem = pintfhdl->io_ops._write_mem;
++
++	_write_mem(pintfhdl, addr, cnt, pmem);
++
++	_func_exit_;
++
++}
++
++void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
++{
++	u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++
++	_func_enter_;
++
++	if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
++	{
++	     RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
++	     return;
++	}
++
++	_read_port = pintfhdl->io_ops._read_port;
++
++	_read_port(pintfhdl, addr, cnt, pmem);
++
++	_func_exit_;
++
++}
++
++void _rtw_read_port_cancel(_adapter *adapter)
++{
++	void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct intf_hdl *pintfhdl = &(pio_priv->intf);
++
++	_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
++
++	if(_read_port_cancel)
++		_read_port_cancel(pintfhdl);
++
++}
++
++u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
++{
++	u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
++	//struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue;
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
++	u32 ret = _SUCCESS;
++
++	_func_enter_;
++
++	_write_port = pintfhdl->io_ops._write_port;
++
++	ret = _write_port(pintfhdl, addr, cnt, pmem);
++
++	 _func_exit_;
++
++	return ret;
++}
++
++u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
++{
++	int ret = _SUCCESS;
++	struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
++	struct submit_ctx sctx;
++
++	rtw_sctx_init(&sctx, timeout_ms);
++	pxmitbuf->sctx = &sctx;
++
++	ret = _rtw_write_port(adapter, addr, cnt, pmem);
++
++	if (ret == _SUCCESS)
++		ret = rtw_sctx_wait(&sctx);
++
++	 return ret;
++}
++
++void _rtw_write_port_cancel(_adapter *adapter)
++{
++	void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
++	struct io_priv *pio_priv = &adapter->iopriv;
++	struct intf_hdl *pintfhdl = &(pio_priv->intf);
++
++	_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
++
++	if(_write_port_cancel)
++		_write_port_cancel(pintfhdl);
++
++}
++
++int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops))
++{
++	struct io_priv	*piopriv = &padapter->iopriv;
++	struct intf_hdl *pintf = &piopriv->intf;
++
++	if (set_intf_ops == NULL)
++		return _FAIL;
++
++	piopriv->padapter = padapter;
++	pintf->padapter = padapter;
++	pintf->pintf_dev = adapter_to_dvobj(padapter);
++
++	set_intf_ops(&pintf->io_ops);
++
++	return _SUCCESS;
++}
++
++#ifdef DBG_IO
++
++u16 read_sniff_ranges[][2] = {
++	//{0x550, 0x551},
++};
++
++u16 write_sniff_ranges[][2] = {
++	//{0x550, 0x551},
++	//{0x4c, 0x4c},
++};
++
++int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2;
++int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2;
++
++bool match_read_sniff_ranges(u16 addr, u16 len)
++{
++	int i;
++	for (i = 0; i<read_sniff_num; i++) {
++		if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
++			return _TRUE;
++	}
++
++	return _FALSE;
++}
++
++bool match_write_sniff_ranges(u16 addr, u16 len)
++{
++	int i;
++	for (i = 0; i<write_sniff_num; i++) {
++		if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
++			return _TRUE;
++	}
++
++	return _FALSE;
++}
++
++u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
++{
++	u8 val = _rtw_read8(adapter, addr);
++
++	if (match_read_sniff_ranges(addr, 1))
++		DBG_871X("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
++
++	return val;
++}
++
++u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
++{
++	u16 val = _rtw_read16(adapter, addr);
++
++	if (match_read_sniff_ranges(addr, 2))
++		DBG_871X("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val);
++
++	return val;
++}
++
++u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
++{
++	u32 val = _rtw_read32(adapter, addr);
++
++	if (match_read_sniff_ranges(addr, 4))
++		DBG_871X("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val);
++
++	return val;
++}
++
++int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, 1))
++		DBG_871X("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val);
++
++	return _rtw_write8(adapter, addr, val);
++}
++int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, 2))
++		DBG_871X("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val);
++
++	return _rtw_write16(adapter, addr, val);
++}
++int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, 4))
++		DBG_871X("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val);
++
++	return _rtw_write32(adapter, addr, val);
++}
++int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, length))
++		DBG_871X("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length);
++
++	return _rtw_writeN(adapter, addr, length, data);
++}
++#endif
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_query.c
+@@ -0,0 +1,195 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_IOCTL_QUERY_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <rtw_ioctl_query.h>
++#include <wifi.h>
++
++
++#ifdef PLATFORM_WINDOWS
++//
++// Added for WPA2-PSK, by Annie, 2005-09-20.
++//
++u8
++query_802_11_capability(
++	_adapter*		Adapter,
++	u8*			pucBuf,
++	u32 *		pulOutLen
++)
++{
++	static NDIS_802_11_AUTHENTICATION_ENCRYPTION szAuthEnc[] =
++	{
++		{Ndis802_11AuthModeOpen, Ndis802_11EncryptionDisabled},
++		{Ndis802_11AuthModeOpen, Ndis802_11Encryption1Enabled},
++		{Ndis802_11AuthModeShared, Ndis802_11EncryptionDisabled},
++		{Ndis802_11AuthModeShared, Ndis802_11Encryption1Enabled},
++		{Ndis802_11AuthModeWPA, Ndis802_11Encryption2Enabled},
++		{Ndis802_11AuthModeWPA, Ndis802_11Encryption3Enabled},
++		{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption2Enabled},
++		{Ndis802_11AuthModeWPAPSK, Ndis802_11Encryption3Enabled},
++		{Ndis802_11AuthModeWPANone, Ndis802_11Encryption2Enabled},
++		{Ndis802_11AuthModeWPANone, Ndis802_11Encryption3Enabled},
++		{Ndis802_11AuthModeWPA2, Ndis802_11Encryption2Enabled},
++		{Ndis802_11AuthModeWPA2, Ndis802_11Encryption3Enabled},
++		{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption2Enabled},
++		{Ndis802_11AuthModeWPA2PSK, Ndis802_11Encryption3Enabled}
++	};
++	static ULONG	ulNumOfPairSupported = sizeof(szAuthEnc)/sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
++	NDIS_802_11_CAPABILITY * pCap = (NDIS_802_11_CAPABILITY *)pucBuf;
++	u8*	pucAuthEncryptionSupported = (u8*) pCap->AuthenticationEncryptionSupported;
++
++
++	pCap->Length = sizeof(NDIS_802_11_CAPABILITY);
++	if(ulNumOfPairSupported > 1 )
++		pCap->Length += 	(ulNumOfPairSupported-1) * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION);
++
++	pCap->Version = 2;
++	pCap->NoOfPMKIDs = NUM_PMKID_CACHE;
++	pCap->NoOfAuthEncryptPairsSupported = ulNumOfPairSupported;
++
++	if( sizeof (szAuthEnc) <= 240 )		// 240 = 256 - 4*4	// SecurityInfo.szCapability: only 256 bytes in size.
++	{
++		_rtw_memcpy( pucAuthEncryptionSupported, (u8*)szAuthEnc,  sizeof (szAuthEnc) );
++		*pulOutLen = pCap->Length;
++		return _TRUE;
++	}
++	else
++	{
++		*pulOutLen = 0;
++		RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("_query_802_11_capability(): szAuthEnc size is too large.\n"));
++		return _FALSE;
++	}
++}
++
++u8 query_802_11_association_information(	_adapter *padapter,PNDIS_802_11_ASSOCIATION_INFORMATION	pAssocInfo)
++{
++	struct wlan_network *tgt_network;
++	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
++	struct	security_priv  *psecuritypriv=&(padapter->securitypriv);
++	WLAN_BSSID_EX	*psecnetwork=(WLAN_BSSID_EX*)&(psecuritypriv->sec_bss);
++	u8 *	pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
++	unsigned char i,*auth_ie,*supp_ie;
++
++	//NdisZeroMemory(pAssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
++	_rtw_memset(pAssocInfo, 0, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
++	//pAssocInfo->Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
++
++	//------------------------------------------------------
++	// Association Request related information
++	//------------------------------------------------------
++	// Req_1. AvailableRequestFixedIEs
++	if(psecnetwork!=NULL){
++
++	pAssocInfo->AvailableRequestFixedIEs |= NDIS_802_11_AI_REQFI_CAPABILITIES|NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;
++	pAssocInfo->RequestFixedIEs.Capabilities = (unsigned short)* & psecnetwork->IEs[10];
++	_rtw_memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress,
++		& psecnetwork->MacAddress, 6);
++
++	pAssocInfo->OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
++
++	if(check_fwstate( pmlmepriv, _FW_UNDER_LINKING|_FW_LINKED)==_TRUE)
++	{
++
++		if(psecuritypriv->ndisauthtype>=Ndis802_11AuthModeWPA2)
++			pDest[0] =48;		//RSN Information Element
++		else
++			pDest[0] =221;	//WPA(SSN) Information Element
++
++		RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n Adapter->ndisauthtype==Ndis802_11AuthModeWPA)?0xdd:0x30 [%d]",pDest[0]));
++		supp_ie=&psecuritypriv->supplicant_ie[0];
++		for(i=0;i<supp_ie[0];i++)
++		{
++			RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("IEs [%d] = 0x%x \n\n", i,supp_ie[i]));
++		}
++
++		i=13;	//0~11 is fixed information element
++		RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("i= %d tgt_network->network.IELength=%d\n\n", i,(int)psecnetwork->IELength));
++		while((i<supp_ie[0]) && (i<256)){
++			if((unsigned char)supp_ie[i]==pDest[0]){
++						_rtw_memcpy((u8 *)(pDest),
++							&supp_ie[i],
++							supp_ie[1+i]+2);
++
++				break;
++			}
++
++			i=i+supp_ie[i+1]+2;
++			if(supp_ie[1+i]==0)
++				i=i+1;
++			RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("iteration i=%d IEs [%d] = 0x%x \n\n", i,i,supp_ie[i+1]));
++
++		}
++
++
++		pAssocInfo->RequestIELength += (2 + supp_ie[1+i]);// (2 + psecnetwork->IEs[1+i]+4);
++
++	}
++
++
++		RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n psecnetwork != NULL,fwstate==_FW_UNDER_LINKING \n"));
++
++	}
++
++
++	//------------------------------------------------------
++	// Association Response related information
++	//------------------------------------------------------
++
++	if(check_fwstate( pmlmepriv, _FW_LINKED)==_TRUE)
++	{
++		tgt_network =&(pmlmepriv->cur_network);
++		if(tgt_network!=NULL){
++		pAssocInfo->AvailableResponseFixedIEs =
++				NDIS_802_11_AI_RESFI_CAPABILITIES
++				|NDIS_802_11_AI_RESFI_ASSOCIATIONID
++				;
++
++		pAssocInfo->ResponseFixedIEs.Capabilities =(unsigned short)* & tgt_network->network.IEs[10];
++		pAssocInfo->ResponseFixedIEs.StatusCode = 0;
++		pAssocInfo->ResponseFixedIEs.AssociationId =(unsigned short) tgt_network->aid;
++
++		pDest = (u8 *)pAssocInfo + sizeof(NDIS_802_11_ASSOCIATION_INFORMATION)+pAssocInfo->RequestIELength;
++		auth_ie=&psecuritypriv->authenticator_ie[0];
++
++		for(i=0;i<auth_ie[0];i++)
++			RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("IEs [%d] = 0x%x \n\n", i,auth_ie[i]));
++
++		i=auth_ie[0]-12;
++		if(i>0){
++			_rtw_memcpy((u8 *)&pDest[0],&auth_ie[1],i);
++			pAssocInfo->ResponseIELength =i;
++		}
++
++
++		pAssocInfo->OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAssocInfo->RequestIELength;
++
++
++		RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n tgt_network != NULL,fwstate==_FW_LINKED \n"));
++		}
++	}
++	RT_TRACE(_module_rtl871x_ioctl_query_c_,_drv_info_,("\n exit query_802_11_association_information \n"));
++_func_exit_;
++
++	return _TRUE;
++}
++#endif
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_rtl.c
+@@ -0,0 +1,1031 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define  _RTW_IOCTL_RTL_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <wlan_bssdef.h>
++#include <wifi.h>
++#include <rtw_ioctl.h>
++#include <rtw_ioctl_set.h>
++#include <rtw_ioctl_query.h>
++#include <rtw_ioctl_rtl.h>
++#include <mp_custom_oid.h>
++#ifdef CONFIG_MP_INCLUDED
++#include <rtw_mp.h>
++#include <rtw_mp_ioctl.h>
++#endif
++
++struct oid_obj_priv oid_rtl_seg_01_01[] =
++{
++	{1, &oid_null_function},										//0x80
++	{1, &oid_null_function},										//0x81
++	{1, &oid_null_function},										//0x82
++	{1, &oid_null_function},										//0x83//OID_RT_SET_SNIFFER_MODE
++	{1, &oid_rt_get_signal_quality_hdl},							//0x84
++	{1, &oid_rt_get_small_packet_crc_hdl},						//0x85
++	{1, &oid_rt_get_middle_packet_crc_hdl},						//0x86
++	{1, &oid_rt_get_large_packet_crc_hdl},						//0x87
++	{1, &oid_rt_get_tx_retry_hdl},								//0x88
++	{1, &oid_rt_get_rx_retry_hdl},								//0x89
++	{1, &oid_rt_pro_set_fw_dig_state_hdl},						//0x8A
++	{1, &oid_rt_pro_set_fw_ra_state_hdl}	,						//0x8B
++	{1, &oid_null_function},										//0x8C
++	{1, &oid_null_function},										//0x8D
++	{1, &oid_null_function},										//0x8E
++	{1, &oid_null_function},										//0x8F
++	{1, &oid_rt_get_rx_total_packet_hdl},							//0x90
++	{1, &oid_rt_get_tx_beacon_ok_hdl},							//0x91
++	{1, &oid_rt_get_tx_beacon_err_hdl},							//0x92
++	{1, &oid_rt_get_rx_icv_err_hdl},								//0x93
++	{1, &oid_rt_set_encryption_algorithm_hdl},					//0x94
++	{1, &oid_null_function},										//0x95
++	{1, &oid_rt_get_preamble_mode_hdl},							//0x96
++	{1, &oid_null_function},										//0x97
++	{1, &oid_rt_get_ap_ip_hdl},									//0x98
++	{1, &oid_rt_get_channelplan_hdl},							//0x99
++	{1, &oid_rt_set_preamble_mode_hdl},	 						//0x9A
++	{1, &oid_rt_set_bcn_intvl_hdl},								//0x9B
++	{1, &oid_null_function},										//0x9C
++	{1, &oid_rt_dedicate_probe_hdl},								//0x9D
++	{1, &oid_null_function},										//0x9E
++	{1, &oid_null_function},										//0x9F
++	{1, &oid_null_function},										//0xA0
++	{1, &oid_null_function},										//0xA1
++	{1, &oid_null_function},										//0xA2
++	{1, &oid_null_function},										//0xA3
++	{1, &oid_null_function},										//0xA4
++	{1, &oid_null_function},										//0xA5
++	{1, &oid_null_function},										//0xA6
++	{1, &oid_rt_get_total_tx_bytes_hdl},							//0xA7
++	{1, &oid_rt_get_total_rx_bytes_hdl},							//0xA8
++	{1, &oid_rt_current_tx_power_level_hdl},						//0xA9
++	{1, &oid_rt_get_enc_key_mismatch_count_hdl},	 			//0xAA
++	{1, &oid_rt_get_enc_key_match_count_hdl},					//0xAB
++	{1, &oid_rt_get_channel_hdl},								//0xAC
++	{1, &oid_rt_set_channelplan_hdl},								//0xAD
++	{1, &oid_rt_get_hardware_radio_off_hdl},						//0xAE
++	{1, &oid_null_function},										//0xAF
++	{1, &oid_null_function},										//0xB0
++	{1, &oid_null_function},										//0xB1
++	{1, &oid_null_function},										//0xB2
++	{1, &oid_null_function},										//0xB3
++	{1, &oid_rt_get_key_mismatch_hdl},							//0xB4
++	{1, &oid_null_function},										//0xB5
++	{1, &oid_null_function},										//0xB6
++	{1, &oid_null_function},										//0xB7
++	{1, &oid_null_function},										//0xB8
++	{1, &oid_null_function},										//0xB9
++	{1, &oid_null_function},	 									//0xBA
++	{1, &oid_rt_supported_wireless_mode_hdl},					//0xBB
++	{1, &oid_rt_get_channel_list_hdl},							//0xBC
++	{1, &oid_rt_get_scan_in_progress_hdl},						//0xBD
++	{1, &oid_null_function},										//0xBE
++	{1, &oid_null_function},										//0xBF
++	{1, &oid_null_function},										//0xC0
++	{1, &oid_rt_forced_data_rate_hdl},							//0xC1
++	{1, &oid_rt_wireless_mode_for_scan_list_hdl},					//0xC2
++	{1, &oid_rt_get_bss_wireless_mode_hdl},						//0xC3
++	{1, &oid_rt_scan_with_magic_packet_hdl},					//0xC4
++	{1, &oid_null_function},										//0xC5
++	{1, &oid_null_function},										//0xC6
++	{1, &oid_null_function},										//0xC7
++	{1, &oid_null_function},										//0xC8
++	{1, &oid_null_function},										//0xC9
++	{1, &oid_null_function},	 									//0xCA
++	{1, &oid_null_function},										//0xCB
++	{1, &oid_null_function},										//0xCC
++	{1, &oid_null_function},										//0xCD
++	{1, &oid_null_function},										//0xCE
++	{1, &oid_null_function},										//0xCF
++
++};
++
++struct oid_obj_priv oid_rtl_seg_01_03[] =
++{
++	{1, &oid_rt_ap_get_associated_station_list_hdl},				//0x00
++	{1, &oid_null_function},										//0x01
++	{1, &oid_rt_ap_switch_into_ap_mode_hdl},					//0x02
++	{1, &oid_null_function},										//0x03
++	{1, &oid_rt_ap_supported_hdl},								//0x04
++	{1, &oid_rt_ap_set_passphrase_hdl},							//0x05
++
++};
++
++struct oid_obj_priv oid_rtl_seg_01_11[] =
++{
++	{1, &oid_null_function},					//0xC0	OID_RT_PRO_RX_FILTER
++	{1, &oid_null_function},					//0xC1	OID_CE_USB_WRITE_REGISTRY
++	{1, &oid_null_function},					//0xC2	OID_CE_USB_READ_REGISTRY
++	{1, &oid_null_function},					//0xC3	OID_RT_PRO_SET_INITIAL_GAIN
++	{1, &oid_null_function},					//0xC4	OID_RT_PRO_SET_BB_RF_STANDBY_MODE
++	{1, &oid_null_function},					//0xC5	OID_RT_PRO_SET_BB_RF_SHUTDOWN_MODE
++	{1, &oid_null_function},					//0xC6	OID_RT_PRO_SET_TX_CHARGE_PUMP
++	{1, &oid_null_function},					//0xC7	OID_RT_PRO_SET_RX_CHARGE_PUMP
++	{1, &oid_rt_pro_rf_write_registry_hdl},	//0xC8
++	{1, &oid_rt_pro_rf_read_registry_hdl},	//0xC9
++	{1, &oid_null_function}					//0xCA	OID_RT_PRO_QUERY_RF_TYPE
++
++};
++
++struct oid_obj_priv oid_rtl_seg_03_00[] =
++{
++	{1, &oid_null_function},										//0x00
++	{1, &oid_rt_get_connect_state_hdl},							//0x01
++	{1, &oid_null_function},										//0x02
++	{1, &oid_null_function},										//0x03
++	{1, &oid_rt_set_default_key_id_hdl},							//0x04
++
++
++};
++
++
++//**************  oid_rtl_seg_01_01 section start **************
++
++NDIS_STATUS oid_rt_pro_set_fw_dig_state_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++#if 0
++	PADAPTER		Adapter = (PADAPTER)(poid_par_priv->adapter_context);
++	_irqL			oldirql;
++
++	_func_enter_;
++
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	_irqlevel_changed_(&oldirql,LOWER);
++	if(poid_par_priv->information_buf_len >= sizeof(struct setdig_parm))
++	{
++		//DEBUG_ERR(("===> oid_rt_pro_set_fw_dig_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf )));
++		if(!rtw_setfwdig_cmd(Adapter,*((unsigned char*)poid_par_priv->information_buf )))
++		{
++			status = NDIS_STATUS_NOT_ACCEPTED;
++		}
++
++	}
++	else{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++	}
++	_irqlevel_changed_(&oldirql,RAISE);
++	_func_exit_;
++#endif
++	return status;
++}
++//-----------------------------------------------------------------------------
++NDIS_STATUS oid_rt_pro_set_fw_ra_state_hdl(struct oid_par_priv* poid_par_priv)
++{
++
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++#if 0
++	PADAPTER		Adapter = (PADAPTER)(poid_par_priv->adapter_context);
++	_irqL			oldirql;
++
++	_func_enter_;
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++
++	_irqlevel_changed_(&oldirql,LOWER);
++
++	if(poid_par_priv->information_buf_len >= sizeof(struct setra_parm))
++	{
++		//DEBUG_ERR(("===> oid_rt_pro_set_fw_ra_state_hdl. type:0x%02x.\n",*((unsigned char*)poid_par_priv->information_buf )));
++		if(!rtw_setfwra_cmd(Adapter,*((unsigned char*)poid_par_priv->information_buf )))
++		{
++			status = NDIS_STATUS_NOT_ACCEPTED;
++		}
++
++	}
++	else{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++	}
++	_irqlevel_changed_(&oldirql,RAISE);
++	_func_exit_;
++#endif
++	return status;
++}
++//-----------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_signal_quality_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	//DEBUG_ERR(("<**********************oid_rt_get_signal_quality_hdl \n"));
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++#if 0
++		if(pMgntInfo->mAssoc || pMgntInfo->mIbss)
++		{
++			ulInfo = pAdapter->RxStats.SignalQuality;
++			*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++		}
++		else
++		{
++			ulInfo = 0xffffffff; // It stands for -1 in 4-byte integer.
++		}
++		break;
++#endif
++
++	return status;
++}
++
++//------------------------------------------------------------------------------
++
++NDIS_STATUS oid_rt_get_small_packet_crc_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	if(poid_par_priv->information_buf_len >=  sizeof(ULONG) )
++	{
++		*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_smallpacket_crcerr;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_middle_packet_crc_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	if(poid_par_priv->information_buf_len >=  sizeof(ULONG) )
++	{
++		*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_middlepacket_crcerr;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_large_packet_crc_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	if(poid_par_priv->information_buf_len >=  sizeof(ULONG) )
++	{
++		*(ULONG *)poid_par_priv->information_buf = padapter->recvpriv.rx_largepacket_crcerr;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++
++
++	return status;
++}
++
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_tx_retry_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_rx_retry_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_rx_total_packet_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	if(poid_par_priv->information_buf_len >=  sizeof(ULONG) )
++	{
++		*(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_pkts + padapter->recvpriv.rx_drop;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_tx_beacon_ok_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_tx_beacon_err_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_rx_icv_err_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	if(poid_par_priv->information_buf_len>= sizeof(u32))
++	{
++		//_rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32));
++		*(uint *)poid_par_priv->information_buf = padapter->recvpriv.rx_icv_err;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH ;
++	}
++
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_set_encryption_algorithm_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_preamble_mode_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++	ULONG			preamblemode = 0 ;
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	if(poid_par_priv->information_buf_len>= sizeof(ULONG))
++	{
++		if(padapter->registrypriv.preamble == PREAMBLE_LONG)
++			preamblemode = 0;
++		else if (padapter->registrypriv.preamble == PREAMBLE_AUTO)
++			preamblemode = 1;
++		else if (padapter->registrypriv.preamble == PREAMBLE_SHORT)
++			preamblemode = 2;
++
++
++		*(ULONG *)poid_par_priv->information_buf = preamblemode ;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH ;
++	}
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_ap_ip_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++
++NDIS_STATUS oid_rt_get_channelplan_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++	struct eeprom_priv*	peeprompriv = &padapter->eeprompriv;
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	*(u16 *)poid_par_priv->information_buf = peeprompriv->channel_plan ;
++
++	return status;
++}
++NDIS_STATUS oid_rt_set_channelplan_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++	struct eeprom_priv*	peeprompriv = &padapter->eeprompriv;
++
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	peeprompriv->channel_plan = *(u16 *)poid_par_priv->information_buf ;
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_set_preamble_mode_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++	ULONG			preamblemode = 0;
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	if(poid_par_priv->information_buf_len>= sizeof(ULONG))
++	{
++		preamblemode = *(ULONG *)poid_par_priv->information_buf ;
++		if( preamblemode == 0)
++			padapter->registrypriv.preamble = PREAMBLE_LONG;
++		else if (preamblemode==1 )
++			padapter->registrypriv.preamble = PREAMBLE_AUTO;
++		else if ( preamblemode==2 )
++			padapter->registrypriv.preamble = PREAMBLE_SHORT;
++
++		*(ULONG *)poid_par_priv->information_buf = preamblemode ;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH ;
++	}
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_set_bcn_intvl_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_dedicate_probe_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_total_tx_bytes_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	if(poid_par_priv->information_buf_len>= sizeof(ULONG))
++	{
++		*(u64 *)poid_par_priv->information_buf = padapter->xmitpriv.tx_bytes;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH ;
++	}
++
++
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_get_total_rx_bytes_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	if(poid_par_priv->information_buf_len>= sizeof(ULONG))
++	{
++		//_rtw_memcpy(*(uint *)poid_par_priv->information_buf,padapter->recvpriv.rx_icv_err,sizeof(u32));
++		*(u64 *)poid_par_priv->information_buf = padapter->recvpriv.rx_bytes;
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else
++	{
++		status = NDIS_STATUS_INVALID_LENGTH ;
++	}
++	return status;
++}
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_current_tx_power_level_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_enc_key_mismatch_count_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_enc_key_match_count_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_channel_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	NDIS_802_11_CONFIGURATION		*pnic_Config;
++
++	ULONG   channelnum;
++
++	_func_enter_;
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	if ( (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
++		(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
++		pnic_Config = &pmlmepriv->cur_network.network.Configuration;
++	else
++		pnic_Config = &padapter->registrypriv.dev_network.Configuration;
++
++	channelnum = pnic_Config->DSConfig;
++	*(ULONG *)poid_par_priv->information_buf = channelnum;
++
++	*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++
++	_func_exit_;
++
++
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_hardware_radio_off_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_key_mismatch_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_supported_wireless_mode_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++	ULONG 			ulInfo = 0 ;
++	//DEBUG_ERR(("<**********************oid_rt_supported_wireless_mode_hdl \n"));
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++	if(poid_par_priv->information_buf_len >= sizeof(ULONG)){
++		ulInfo |= 0x0100; //WIRELESS_MODE_B
++		ulInfo |= 0x0200; //WIRELESS_MODE_G
++		ulInfo |= 0x0400; //WIRELESS_MODE_A
++
++		*(ULONG *) poid_par_priv->information_buf = ulInfo;
++		//DEBUG_ERR(("<===oid_rt_supported_wireless_mode %x\n",ulInfo));
++		*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
++	}
++	else{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_channel_list_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_scan_in_progress_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++
++
++NDIS_STATUS oid_rt_forced_data_rate_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++NDIS_STATUS oid_rt_wireless_mode_for_scan_list_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++NDIS_STATUS oid_rt_get_bss_wireless_mode_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++
++NDIS_STATUS oid_rt_scan_with_magic_packet_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++//**************  oid_rtl_seg_01_01 section end **************
++
++//**************  oid_rtl_seg_01_03 section start **************
++NDIS_STATUS oid_rt_ap_get_associated_station_list_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++NDIS_STATUS oid_rt_ap_switch_into_ap_mode_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++NDIS_STATUS oid_rt_ap_supported_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	return status;
++}
++NDIS_STATUS oid_rt_ap_set_passphrase_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++
++//**************  oid_rtl_seg_01_03 section end **************
++
++//****************  oid_rtl_seg_01_11   section start ****************
++NDIS_STATUS oid_rt_pro_rf_write_registry_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++	PADAPTER		Adapter = (PADAPTER)(poid_par_priv->adapter_context);
++	_irqL			oldirql;
++	_func_enter_;
++	//DEBUG_ERR(("<**********************oid_rt_pro_rf_write_registry_hdl \n"));
++	if(poid_par_priv->type_of_oid != SET_OID) //QUERY_OID
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	_irqlevel_changed_(&oldirql,LOWER);
++	if(poid_par_priv->information_buf_len== (sizeof(unsigned long)*3))
++	{
++		//RegOffsetValue	- The offset of RF register to write.
++		//RegDataWidth	- The data width of RF register to write.
++		//RegDataValue	- The value to write.
++		//RegOffsetValue = *((unsigned long*)InformationBuffer);
++		//RegDataWidth = *((unsigned long*)InformationBuffer+1);
++		//RegDataValue =  *((unsigned long*)InformationBuffer+2);
++		if(!rtw_setrfreg_cmd(Adapter,
++						*(unsigned char*)poid_par_priv->information_buf,
++						(unsigned long)(*((unsigned long*)poid_par_priv->information_buf+2))))
++		{
++			status = NDIS_STATUS_NOT_ACCEPTED;
++		}
++
++	}
++	else{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++	_irqlevel_changed_(&oldirql,RAISE);
++	_func_exit_;
++
++	return status;
++}
++
++//------------------------------------------------------------------------------
++NDIS_STATUS oid_rt_pro_rf_read_registry_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++#if 0
++	PADAPTER		Adapter = (PADAPTER)(poid_par_priv->adapter_context);
++	_irqL	oldirql;
++	_func_enter_;
++
++	//DEBUG_ERR(("<**********************oid_rt_pro_rf_read_registry_hdl \n"));
++	if(poid_par_priv->type_of_oid != SET_OID) //QUERY_OID
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	_irqlevel_changed_(&oldirql,LOWER);
++	if(poid_par_priv->information_buf_len== (sizeof(unsigned long)*3))
++	{
++		if(Adapter->mppriv.act_in_progress == _TRUE)
++		{
++			status = NDIS_STATUS_NOT_ACCEPTED;
++		}
++		else
++		{
++			//init workparam
++			Adapter->mppriv.act_in_progress = _TRUE;
++			Adapter->mppriv.workparam.bcompleted= _FALSE;
++			Adapter->mppriv.workparam.act_type = MPT_READ_RF;
++			Adapter->mppriv.workparam.io_offset = *(unsigned long*)poid_par_priv->information_buf;
++			Adapter->mppriv.workparam.io_value = 0xcccccccc;
++
++			//RegOffsetValue	- The offset of RF register to read.
++			//RegDataWidth	- The data width of RF register to read.
++			//RegDataValue	- The value to read.
++			//RegOffsetValue = *((unsigned long*)InformationBuffer);
++			//RegDataWidth = *((unsigned long*)InformationBuffer+1);
++			//RegDataValue =  *((unsigned long*)InformationBuffer+2);
++			if(!rtw_getrfreg_cmd(Adapter,
++							*(unsigned char*)poid_par_priv->information_buf,
++							(unsigned char*)&Adapter->mppriv.workparam.io_value))
++			{
++				status = NDIS_STATUS_NOT_ACCEPTED;
++			}
++		}
++
++
++	}
++	else	{
++		status = NDIS_STATUS_INVALID_LENGTH;
++	}
++	_irqlevel_changed_(&oldirql,RAISE);
++	_func_exit_;
++#endif
++	return status;
++}
++
++//****************  oid_rtl_seg_01_11   section end****************
++
++
++//**************  oid_rtl_seg_03_00 section start **************
++enum _CONNECT_STATE_{
++	CHECKINGSTATUS,
++	ASSOCIATED,
++	ADHOCMODE,
++	NOTASSOCIATED
++};
++
++NDIS_STATUS oid_rt_get_connect_state_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS		status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
++
++	ULONG ulInfo;
++
++	if(poid_par_priv->type_of_oid != QUERY_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	// nStatus==0	CheckingStatus
++	// nStatus==1	Associated
++	// nStatus==2	AdHocMode
++	// nStatus==3	NotAssociated
++
++	if(check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
++		ulInfo = CHECKINGSTATUS;
++	else if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++		ulInfo = ASSOCIATED;
++	else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)== _TRUE)
++		ulInfo = ADHOCMODE;
++	else
++		ulInfo = NOTASSOCIATED ;
++
++	*(ULONG *)poid_par_priv->information_buf = ulInfo;
++	*poid_par_priv->bytes_rw =  poid_par_priv->information_buf_len;
++
++#if 0
++	// Rearrange the order to let the UI still shows connection when scan is in progress
++	RT_TRACE(COMP_OID_QUERY, DBG_LOUD, ("===> Query OID_RT_GET_CONNECT_STATE.\n"));
++	if(pMgntInfo->mAssoc)
++		ulInfo = 1;
++	else if(pMgntInfo->mIbss)
++		ulInfo = 2;
++	else if(pMgntInfo->bScanInProgress)
++		ulInfo = 0;
++	else
++		ulInfo = 3;
++	ulInfoLen = sizeof(ULONG);
++	RT_TRACE(COMP_OID_QUERY, DBG_LOUD, ("<=== Query OID_RT_GET_CONNECT_STATE: %d\n", ulInfo));
++#endif
++
++	return status;
++}
++
++NDIS_STATUS oid_rt_set_default_key_id_hdl(struct oid_par_priv* poid_par_priv)
++{
++	NDIS_STATUS	 	status = NDIS_STATUS_SUCCESS;
++	PADAPTER		padapter = (PADAPTER)(poid_par_priv->adapter_context);
++
++	if(poid_par_priv->type_of_oid != SET_OID)
++	{
++		status = NDIS_STATUS_NOT_ACCEPTED;
++		return status;
++	}
++
++	return status;
++}
++//**************  oid_rtl_seg_03_00 section end **************
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_ioctl_set.c
+@@ -0,0 +1,1493 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_IOCTL_SET_C_
++
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <rtw_ioctl_set.h>
++#include <hal_intf.h>
++
++#ifdef CONFIG_USB_HCI
++#include <usb_osintf.h>
++#include <usb_ops.h>
++#endif
++#ifdef CONFIG_SDIO_HCI
++#include <sdio_osintf.h>
++#endif
++
++extern void indicate_wx_scan_complete_event(_adapter *padapter);
++
++#define IS_MAC_ADDRESS_BROADCAST(addr) \
++( \
++	( (addr[0] == 0xff) && (addr[1] == 0xff) && \
++		(addr[2] == 0xff) && (addr[3] == 0xff) && \
++		(addr[4] == 0xff) && (addr[5] == 0xff) )  ? _TRUE : _FALSE \
++)
++
++u8 rtw_validate_bssid(u8 *bssid)
++{
++	u8 ret = _TRUE;
++
++	if (is_zero_mac_addr(bssid)
++		|| is_broadcast_mac_addr(bssid)
++		|| is_multicast_mac_addr(bssid)
++	) {
++		ret = _FALSE;
++	}
++
++	return ret;
++}
++
++u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
++{
++	u8	 i;
++	u8	ret=_TRUE;
++
++_func_enter_;
++
++	if (ssid->SsidLength > 32) {
++		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid length >32\n"));
++		ret= _FALSE;
++		goto exit;
++	}
++
++#ifdef CONFIG_VALIDATE_SSID
++	for(i = 0; i < ssid->SsidLength; i++)
++	{
++		//wifi, printable ascii code must be supported
++		if(!( (ssid->Ssid[i] >= 0x20) && (ssid->Ssid[i] <= 0x7e) )){
++			RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("ssid has nonprintabl ascii\n"));
++			ret= _FALSE;
++			break;
++		}
++	}
++#endif /* CONFIG_VALIDATE_SSID */
++
++exit:
++
++_func_exit_;
++
++	return ret;
++}
++
++u8 rtw_do_join(_adapter * padapter);
++u8 rtw_do_join(_adapter * padapter)
++{
++	_irqL	irqL;
++	_list	*plist, *phead;
++	u8* pibss = NULL;
++	struct	mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
++	_queue	*queue	= &(pmlmepriv->scanned_queue);
++	u8 ret=_SUCCESS;
++
++_func_enter_;
++
++	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++	phead = get_list_head(queue);
++	plist = get_next(phead);
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("\n rtw_do_join: phead = %p; plist = %p \n\n\n", phead, plist));
++
++	pmlmepriv->cur_network.join_res = -2;
++
++	set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
++
++	pmlmepriv->pscanned = plist;
++
++	pmlmepriv->to_join = _TRUE;
++
++	if(_rtw_queue_empty(queue)== _TRUE)
++	{
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++
++		//when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty
++		//we try to issue sitesurvey firstly
++
++		if (pmlmepriv->LinkDetectInfo.bBusyTraffic ==_FALSE
++			|| rtw_to_roaming(padapter) > 0
++		)
++		{
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_do_join(): site survey if scanned_queue is empty\n."));
++			// submit site_survey_cmd
++			if(_SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ) {
++				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_do_join(): site survey return error\n."));
++			}
++		}
++
++		goto exit;
++	}
++	else
++	{
++		int select_ret;
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		if((select_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv))==_SUCCESS)
++		{
++			pmlmepriv->to_join = _FALSE;
++			_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
++		}
++		else if(ret == 2)//there is no need to wait for join
++		{
++			ret = _SUCCESS;
++			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++			rtw_indicate_connect(padapter);
++		}
++		else
++		{
++			if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE)
++			{
++				// submit createbss_cmd to change to a ADHOC_MASTER
++
++				//pmlmepriv->lock has been acquired by caller...
++				WLAN_BSSID_EX    *pdev_network = &(padapter->registrypriv.dev_network);
++
++				pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
++
++				pibss = padapter->registrypriv.dev_network.MacAddress;
++
++				_rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
++				_rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
++
++				rtw_update_registrypriv_dev_network(padapter);
++
++				rtw_generate_random_ibss(pibss);
++
++				if(rtw_createbss_cmd(padapter)!=_SUCCESS)
++				{
++					RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>do_goin: rtw_createbss_cmd status FAIL*** \n "));
++					ret =  _FALSE;
++					goto exit;
++				}
++
++				pmlmepriv->to_join = _FALSE;
++
++				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("***Error=> rtw_select_and_join_from_scanned_queue FAIL under STA_Mode*** \n "));
++
++			}
++			else
++			{
++				// can't associate ; reset under-linking
++				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++
++#if 0
++				if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE))
++				{
++					if(_rtw_memcmp(pmlmepriv->cur_network.network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength))
++					{
++						// for funk to do roaming
++						// funk will reconnect, but funk will not sitesurvey before reconnect
++						RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("for funk to do roaming"));
++						if(pmlmepriv->sitesurveyctrl.traffic_busy==_FALSE)
++							rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0);
++					}
++
++				}
++#endif
++
++				//when set_ssid/set_bssid for rtw_do_join(), but there are no desired bss in scanning queue
++				//we try to issue sitesurvey firstly
++				if(pmlmepriv->LinkDetectInfo.bBusyTraffic==_FALSE
++					|| rtw_to_roaming(padapter) > 0
++				)
++				{
++					//DBG_871X("rtw_do_join() when   no desired bss in scanning queue \n");
++					if( _SUCCESS!=(ret=rtw_sitesurvey_cmd(padapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)) ){
++						RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("do_join(): site survey return error\n."));
++					}
++				}
++
++
++			}
++
++		}
++
++	}
++
++exit:
++
++_func_exit_;
++
++	return ret;
++}
++
++#ifdef PLATFORM_WINDOWS
++u8 rtw_pnp_set_power_wakeup(_adapter* padapter)
++{
++	u8 res=_SUCCESS;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("==>rtw_pnp_set_power_wakeup!!!\n"));
++
++	res = rtw_setstandby_cmd(padapter, 0);
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<==rtw_pnp_set_power_wakeup!!!\n"));
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_pnp_set_power_sleep(_adapter* padapter)
++{
++	u8 res=_SUCCESS;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("==>rtw_pnp_set_power_sleep!!!\n"));
++	//DbgPrint("+rtw_pnp_set_power_sleep\n");
++
++	res = rtw_setstandby_cmd(padapter, 1);
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<==rtw_pnp_set_power_sleep!!!\n"));
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_set_802_11_reload_defaults(_adapter * padapter, NDIS_802_11_RELOAD_DEFAULTS reloadDefaults)
++{
++_func_enter_;
++
++	switch( reloadDefaults)
++	{
++		case Ndis802_11ReloadWEPKeys:
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("SetInfo OID_802_11_RELOAD_DEFAULTS : Ndis802_11ReloadWEPKeys\n"));
++			break;
++	}
++
++	// SecClearAllKeys(Adapter);
++	// 8711 CAM was not for En/Decrypt only
++	// so, we can't clear all keys.
++	// should we disable WPAcfg (ox0088) bit 1-2, instead of clear all CAM
++
++	//TO DO...
++
++_func_exit_;
++
++	return _TRUE;
++}
++
++u8 set_802_11_test(_adapter* padapter, NDIS_802_11_TEST *test)
++{
++	u8 ret=_TRUE;
++
++_func_enter_;
++
++	switch(test->Type)
++	{
++		case 1:
++			NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->AuthenticationEvent, test->Length - 8);
++			NdisMIndicateStatusComplete(padapter->hndis_adapter);
++			break;
++
++		case 2:
++			NdisMIndicateStatus(padapter->hndis_adapter, NDIS_STATUS_MEDIA_SPECIFIC_INDICATION, (PVOID)&test->RssiTrigger, sizeof(NDIS_802_11_RSSI));
++			NdisMIndicateStatusComplete(padapter->hndis_adapter);
++			break;
++
++		default:
++			ret=_FALSE;
++			break;
++	}
++
++_func_exit_;
++
++	return ret;
++}
++
++u8	rtw_set_802_11_pmkid(_adapter*	padapter, NDIS_802_11_PMKID *pmkid)
++{
++	u8	ret=_SUCCESS;
++
++	return ret;
++}
++
++#endif
++
++u8 rtw_set_802_11_bssid(_adapter* padapter, u8 *bssid)
++{
++	_irqL irqL;
++	u8 status=_SUCCESS;
++	u32 cur_time = 0;
++
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
++		 ("+rtw_set_802_11_bssid: bssid="MAC_FMT"\n", MAC_ARG(bssid) ));
++
++	if ((bssid[0]==0x00 && bssid[1]==0x00 && bssid[2]==0x00 && bssid[3]==0x00 && bssid[4]==0x00 &&bssid[5]==0x00) ||
++	    (bssid[0]==0xFF && bssid[1]==0xFF && bssid[2]==0xFF && bssid[3]==0xFF && bssid[4]==0xFF &&bssid[5]==0xFF))
++	{
++		status = _FAIL;
++		goto exit;
++	}
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++
++	DBG_871X("Set BSSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
++		goto handle_tkip_countermeasure;
++	} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
++		goto release_mlme_lock;
++	}
++
++	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
++	{
++		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
++
++		if (_rtw_memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN) == _TRUE)
++		{
++			if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE)
++				goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again.
++		} else {
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set BSSID not the same bssid\n"));
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_bssid="MAC_FMT"\n", MAC_ARG(bssid) ));
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("cur_bssid="MAC_FMT"\n", MAC_ARG(pmlmepriv->cur_network.network.MacAddress) ));
++
++			rtw_disassoc_cmd(padapter, 0, _TRUE);
++
++			if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++				rtw_indicate_disconnect(padapter);
++
++			rtw_free_assoc_resources(padapter, 1);
++
++			if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
++				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
++				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
++			}
++		}
++	}
++
++handle_tkip_countermeasure:
++	if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
++		status = _FAIL;
++		goto release_mlme_lock;
++	}
++
++	_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
++	pmlmepriv->assoc_by_bssid=_TRUE;
++
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
++		pmlmepriv->to_join = _TRUE;
++	}
++	else {
++		status = rtw_do_join(padapter);
++	}
++
++release_mlme_lock:
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++exit:
++	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
++		("rtw_set_802_11_bssid: status=%d\n", status));
++
++_func_exit_;
++
++	return status;
++}
++
++u8 rtw_set_802_11_ssid(_adapter* padapter, NDIS_802_11_SSID *ssid)
++{
++	_irqL irqL;
++	u8 status = _SUCCESS;
++	u32 cur_time = 0;
++
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct wlan_network *pnetwork = &pmlmepriv->cur_network;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
++		 ("+rtw_set_802_11_ssid: ssid=[%s] fw_state=0x%08x\n",
++		  ssid->Ssid, get_fwstate(pmlmepriv)));
++
++	if(padapter->hw_init_completed==_FALSE){
++		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
++			 ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n"));
++		status = _FAIL;
++		goto exit;
++	}
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	DBG_871X("Set SSID under fw_state=0x%08x\n", get_fwstate(pmlmepriv));
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
++		goto handle_tkip_countermeasure;
++	} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
++		goto release_mlme_lock;
++	}
++
++	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE) == _TRUE)
++	{
++		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
++			 ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
++
++		if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) &&
++		    (_rtw_memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength) == _TRUE))
++		{
++			if((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE))
++			{
++				RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
++					 ("Set SSID is the same ssid, fw_state=0x%08x\n",
++					  get_fwstate(pmlmepriv)));
++
++				if(rtw_is_same_ibss(padapter, pnetwork) == _FALSE)
++				{
++					//if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again
++					rtw_disassoc_cmd(padapter, 0, _TRUE);
++
++					if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++						rtw_indicate_disconnect(padapter);
++
++					rtw_free_assoc_resources(padapter, 1);
++
++					if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
++						_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
++						set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
++					}
++				}
++				else
++				{
++					goto release_mlme_lock;//it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again.
++				}
++			}
++#ifdef CONFIG_LPS
++			else {
++				rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_JOINBSS, 1);
++			}
++#endif
++		}
++		else
++		{
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("Set SSID not the same ssid\n"));
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_ssid=[%s] len=0x%x\n", ssid->Ssid, (unsigned int)ssid->SsidLength));
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("assoc_ssid=[%s] len=0x%x\n", pmlmepriv->assoc_ssid.Ssid, (unsigned int)pmlmepriv->assoc_ssid.SsidLength));
++
++			rtw_disassoc_cmd(padapter, 0, _TRUE);
++
++			if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++				rtw_indicate_disconnect(padapter);
++
++			rtw_free_assoc_resources(padapter, 1);
++
++			if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
++				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
++				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
++			}
++		}
++	}
++
++handle_tkip_countermeasure:
++	if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
++		status = _FAIL;
++		goto release_mlme_lock;
++	}
++
++	if (rtw_validate_ssid(ssid) == _FALSE) {
++		status = _FAIL;
++		goto release_mlme_lock;
++	}
++
++	_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
++	pmlmepriv->assoc_by_bssid=_FALSE;
++
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
++		pmlmepriv->to_join = _TRUE;
++	}
++	else {
++		status = rtw_do_join(padapter);
++	}
++
++release_mlme_lock:
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++exit:
++	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
++		("-rtw_set_802_11_ssid: status=%d\n", status));
++
++_func_exit_;
++
++	return status;
++
++}
++
++u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
++{
++	_irqL irqL;
++	u8 status = _SUCCESS;
++	u32 cur_time = 0;
++	bool bssid_valid = _TRUE;
++	bool ssid_valid = _TRUE;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
++		ssid_valid = _FALSE;
++
++	if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
++		bssid_valid = _FALSE;
++
++	if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
++		DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
++			FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
++		status = _FAIL;
++		goto exit;
++	}
++
++	if(padapter->hw_init_completed==_FALSE){
++		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
++			 ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n"));
++		status = _FAIL;
++		goto exit;
++	}
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	LOG_LEVEL(_drv_info_, FUNC_ADPT_FMT"  fw_state=0x%08x\n",
++		FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
++
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
++		goto handle_tkip_countermeasure;
++	} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
++		goto release_mlme_lock;
++	}
++
++handle_tkip_countermeasure:
++	if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
++		status = _FAIL;
++		goto release_mlme_lock;
++	}
++
++	if (ssid && ssid_valid)
++		_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
++
++	if (bssid && bssid_valid) {
++		_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
++		pmlmepriv->assoc_by_bssid = _TRUE;
++	}
++
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
++		pmlmepriv->to_join = _TRUE;
++	}
++	else {
++		status = rtw_do_join(padapter);
++	}
++
++release_mlme_lock:
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++exit:
++
++_func_exit_;
++
++	return status;
++}
++
++/*
++rtw_set_802_11_infrastructure_mode(~)
++	### NOTE:#### (!!!!)
++	MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock and scanned_queue->lock in sequence
++*/
++u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter,
++	NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
++{
++	_irqL irqL;
++	struct	mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	struct	wlan_network	*cur_network = &pmlmepriv->cur_network;
++	NDIS_802_11_NETWORK_INFRASTRUCTURE* pold_state = &(cur_network->network.InfrastructureMode);
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_notice_,
++		 ("+rtw_set_802_11_infrastructure_mode: old=%d new=%d fw_state=0x%08x\n",
++		  *pold_state, networktype, get_fwstate(pmlmepriv)));
++
++	if(*pold_state != networktype)
++	{
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,(" change mode!"));
++		//DBG_871X("change mode, old_mode=%d, new_mode=%d, fw_state=0x%x\n", *pold_state, networktype, get_fwstate(pmlmepriv));
++
++		if(*pold_state==Ndis802_11APMode)
++		{
++			//change to other mode from Ndis802_11APMode
++			cur_network->join_res = -1;
++
++#ifdef CONFIG_NATIVEAP_MLME
++			stop_ap_mode(padapter);
++#endif
++		}
++
++		if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||(*pold_state==Ndis802_11IBSS))
++			rtw_disassoc_cmd(padapter, 0, _TRUE);
++
++		if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) ||
++			(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)== _TRUE) )
++			rtw_free_assoc_resources(padapter, 0);
++
++		if((*pold_state == Ndis802_11Infrastructure) ||(*pold_state == Ndis802_11IBSS))
++	       {
++			if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++			{
++				rtw_indicate_disconnect(padapter); //will clr Linked_state; before this function, we must have chked whether  issue dis-assoc_cmd or not
++			}
++	       }
++
++		*pold_state = networktype;
++
++		_clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
++
++		switch(networktype)
++		{
++			case Ndis802_11IBSS:
++				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
++				break;
++
++			case Ndis802_11Infrastructure:
++				set_fwstate(pmlmepriv, WIFI_STATION_STATE);
++				break;
++
++			case Ndis802_11APMode:
++				set_fwstate(pmlmepriv, WIFI_AP_STATE);
++#ifdef CONFIG_NATIVEAP_MLME
++				start_ap_mode(padapter);
++				//rtw_indicate_connect(padapter);
++#endif
++
++				break;
++
++			case Ndis802_11AutoUnknown:
++			case Ndis802_11InfrastructureMax:
++				break;
++		}
++
++		//SecClearAllKeys(adapter);
++
++		//RT_TRACE(COMP_OID_SET, DBG_LOUD, ("set_infrastructure: fw_state:%x after changing mode\n",
++		//									get_fwstate(pmlmepriv) ));
++
++	}
++
++_func_exit_;
++
++	return _TRUE;
++}
++
++
++u8 rtw_set_802_11_disassociate(_adapter *padapter)
++{
++	_irqL irqL;
++	struct mlme_priv * pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++	{
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_disassociate: rtw_indicate_disconnect\n"));
++
++		rtw_disassoc_cmd(padapter, 0, _TRUE);
++		rtw_indicate_disconnect(padapter);
++		//modify for CONFIG_IEEE80211W, none 11w can use it
++		rtw_free_assoc_resources_cmd(padapter);
++	}
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++_func_exit_;
++
++	return _TRUE;
++}
++
++u8 rtw_set_802_11_bssid_list_scan(_adapter* padapter, NDIS_802_11_SSID *pssid, int ssid_max_num)
++{
++	_irqL	irqL;
++	struct	mlme_priv		*pmlmepriv= &padapter->mlmepriv;
++	u8	res=_TRUE;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("+rtw_set_802_11_bssid_list_scan(), fw_state=%x\n", get_fwstate(pmlmepriv)));
++
++	if (padapter == NULL) {
++		res=_FALSE;
++		goto exit;
++	}
++	if (padapter->hw_init_completed==_FALSE){
++		res = _FALSE;
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n===rtw_set_802_11_bssid_list_scan:hw_init_completed==_FALSE===\n"));
++		goto exit;
++	}
++
++	if ((check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) ||
++		(pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
++	{
++		// Scan or linking is in progress, do nothing.
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_bssid_list_scan fail since fw_state = %x\n", get_fwstate(pmlmepriv)));
++		res = _TRUE;
++
++		if(check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))== _TRUE){
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n"));
++		} else {
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n###pmlmepriv->sitesurveyctrl.traffic_busy==_TRUE\n\n"));
++		}
++	} else {
++		if (rtw_is_scan_deny(padapter)) {
++			DBG_871X(FUNC_ADPT_FMT": scan deny\n", FUNC_ADPT_ARG(padapter));
++			indicate_wx_scan_complete_event(padapter);
++			return _SUCCESS;
++		}
++
++		_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++		res = rtw_sitesurvey_cmd(padapter, pssid, ssid_max_num, NULL, 0);
++
++		_exit_critical_bh(&pmlmepriv->lock, &irqL);
++	}
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++u8 rtw_set_802_11_authentication_mode(_adapter* padapter, NDIS_802_11_AUTHENTICATION_MODE authmode)
++{
++	struct security_priv *psecuritypriv = &padapter->securitypriv;
++	int res;
++	u8 ret;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("set_802_11_auth.mode(): mode=%x\n", authmode));
++
++	psecuritypriv->ndisauthtype=authmode;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_authentication_mode:psecuritypriv->ndisauthtype=%d", psecuritypriv->ndisauthtype));
++
++	if(psecuritypriv->ndisauthtype>3)
++		psecuritypriv->dot11AuthAlgrthm=dot11AuthAlgrthm_8021X;
++
++	res=rtw_set_auth(padapter,psecuritypriv);
++
++	if(res==_SUCCESS)
++		ret=_TRUE;
++	else
++		ret=_FALSE;
++
++_func_exit_;
++
++	return ret;
++}
++
++u8 rtw_set_802_11_add_wep(_adapter* padapter, NDIS_802_11_WEP *wep){
++
++	u8		bdefaultkey;
++	u8		btransmitkey;
++	sint		keyid,res;
++	struct security_priv* psecuritypriv=&(padapter->securitypriv);
++	u8		ret=_SUCCESS;
++
++_func_enter_;
++
++	bdefaultkey=(wep->KeyIndex & 0x40000000) > 0 ? _FALSE : _TRUE;   //for ???
++	btransmitkey= (wep->KeyIndex & 0x80000000) > 0 ? _TRUE  : _FALSE;	//for ???
++	keyid=wep->KeyIndex & 0x3fffffff;
++
++	if(keyid>4)
++	{
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MgntActrtw_set_802_11_add_wep:keyid>4=>fail\n"));
++		ret=_FALSE;
++		goto exit;
++	}
++
++	switch(wep->KeyLength)
++	{
++		case 5:
++			psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=5\n"));
++			break;
++		case 13:
++			psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength=13\n"));
++			break;
++		default:
++			psecuritypriv->dot11PrivacyAlgrthm=_NO_PRIVACY_;
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("MgntActrtw_set_802_11_add_wep:wep->KeyLength!=5 or 13\n"));
++			break;
++	}
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:befor memcpy, wep->KeyLength=0x%x wep->KeyIndex=0x%x  keyid =%x\n",wep->KeyLength,wep->KeyIndex,keyid));
++
++	_rtw_memcpy(&(psecuritypriv->dot11DefKey[keyid].skey[0]),&(wep->KeyMaterial),wep->KeyLength);
++
++	psecuritypriv->dot11DefKeylen[keyid]=wep->KeyLength;
++
++	psecuritypriv->dot11PrivacyKeyIndex=keyid;
++
++	RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_wep:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x \n",
++		psecuritypriv->dot11DefKey[keyid].skey[0],psecuritypriv->dot11DefKey[keyid].skey[1],psecuritypriv->dot11DefKey[keyid].skey[2],
++		psecuritypriv->dot11DefKey[keyid].skey[3],psecuritypriv->dot11DefKey[keyid].skey[4],psecuritypriv->dot11DefKey[keyid].skey[5],
++		psecuritypriv->dot11DefKey[keyid].skey[6],psecuritypriv->dot11DefKey[keyid].skey[7],psecuritypriv->dot11DefKey[keyid].skey[8],
++		psecuritypriv->dot11DefKey[keyid].skey[9],psecuritypriv->dot11DefKey[keyid].skey[10],psecuritypriv->dot11DefKey[keyid].skey[11],
++		psecuritypriv->dot11DefKey[keyid].skey[12]));
++
++	res=rtw_set_key(padapter,psecuritypriv, keyid, 1);
++
++	if(res==_FAIL)
++		ret= _FALSE;
++exit:
++
++_func_exit_;
++
++	return ret;
++
++}
++
++u8 rtw_set_802_11_remove_wep(_adapter* padapter, u32 keyindex){
++
++	u8 ret=_SUCCESS;
++
++_func_enter_;
++
++	if (keyindex >= 0x80000000 || padapter == NULL){
++
++		ret=_FALSE;
++		goto exit;
++
++	}
++	else
++	{
++		int res;
++		struct security_priv* psecuritypriv=&(padapter->securitypriv);
++		if( keyindex < 4 ){
++
++			_rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16);
++
++			res=rtw_set_key(padapter,psecuritypriv,keyindex, 0);
++
++			psecuritypriv->dot11DefKeylen[keyindex]=0;
++
++			if(res==_FAIL)
++				ret=_FAIL;
++
++		}
++		else
++		{
++			ret=_FAIL;
++		}
++
++	}
++
++exit:
++
++_func_exit_;
++
++	return ret;
++
++}
++
++u8 rtw_set_802_11_add_key(_adapter* padapter, NDIS_802_11_KEY *key){
++
++	uint	encryptionalgo;
++	u8 * pbssid;
++	struct sta_info *stainfo;
++	u8	bgroup = _FALSE;
++	u8	bgrouptkey = _FALSE;//can be remove later
++	u8	ret=_SUCCESS;
++
++_func_enter_;
++
++	if (((key->KeyIndex & 0x80000000) == 0) && ((key->KeyIndex & 0x40000000) > 0)){
++
++		// It is invalid to clear bit 31 and set bit 30. If the miniport driver encounters this combination,
++		// it must fail the request and return NDIS_STATUS_INVALID_DATA.
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: ((key->KeyIndex & 0x80000000) == 0)[=%d] ",(int)(key->KeyIndex & 0x80000000) == 0));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key:((key->KeyIndex & 0x40000000) > 0)[=%d]" , (int)(key->KeyIndex & 0x40000000) > 0));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_add_key: key->KeyIndex=%d \n" ,(int)key->KeyIndex));
++		ret= _FAIL;
++		goto exit;
++	}
++
++	if(key->KeyIndex & 0x40000000)
++	{
++		// Pairwise key
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Pairwise key +++++\n"));
++
++		pbssid=get_bssid(&padapter->mlmepriv);
++		stainfo=rtw_get_stainfo(&padapter->stapriv, pbssid);
++
++		if((stainfo!=NULL)&&(padapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)){
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:( stainfo!=NULL)&&(Adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)\n"));
++			encryptionalgo=stainfo->dot118021XPrivacy;
++		}
++		else{
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: stainfo==NULL)||(Adapter->securitypriv.dot11AuthAlgrthm!=dot11AuthAlgrthm_8021X)\n"));
++			encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm;
++		}
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (encryptionalgo ==%d)!\n",encryptionalgo ));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11PrivacyAlgrthm ==%d)!\n",padapter->securitypriv.dot11PrivacyAlgrthm));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (Adapter->securitypriv.dot11AuthAlgrthm ==%d)!\n",padapter->securitypriv.dot11AuthAlgrthm));
++
++		if((stainfo!=NULL)){
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("rtw_set_802_11_add_key: (stainfo->dot118021XPrivacy ==%d)!\n", stainfo->dot118021XPrivacy));
++		}
++
++		if(key->KeyIndex & 0x000000FF){
++			// The key index is specified in the lower 8 bits by values of zero to 255.
++			// The key index should be set to zero for a Pairwise key, and the driver should fail with
++			// NDIS_STATUS_INVALID_DATA if the lower 8 bits is not zero
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" key->KeyIndex & 0x000000FF.\n"));
++			ret= _FAIL;
++			goto exit;
++		}
++
++		// check BSSID
++		if (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _TRUE){
++
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("MacAddr_isBcst(key->BSSID)\n"));
++			ret= _FALSE;
++			goto exit;
++		}
++
++		// Check key length for TKIP.
++		//if(encryptionAlgorithm == RT_ENC_TKIP_ENCRYPTION && key->KeyLength != 32)
++		if((encryptionalgo== _TKIP_)&& (key->KeyLength != 32)){
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("TKIP KeyLength:0x%x != 32\n", key->KeyLength));
++			ret=_FAIL;
++			goto exit;
++
++		}
++
++		// Check key length for AES.
++		if((encryptionalgo== _AES_)&& (key->KeyLength != 16)) {
++			// For our supplicant, EAPPkt9x.vxd, cannot differentiate TKIP and AES case.
++			if(key->KeyLength == 32) {
++				key->KeyLength = 16;
++			} else {
++				ret= _FAIL;
++				goto exit;
++			}
++		}
++
++		// Check key length for WEP. For NDTEST, 2005.01.27, by rcnjko.
++		if(	(encryptionalgo== _WEP40_|| encryptionalgo== _WEP104_) && (key->KeyLength != 5 || key->KeyLength != 13)) {
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("WEP KeyLength:0x%x != 5 or 13\n", key->KeyLength));
++			ret=_FAIL;
++			goto exit;
++		}
++
++		bgroup = _FALSE;
++
++		// Check the pairwise key. Added by Annie, 2005-07-06.
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Pairwise Key set]\n"));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3)));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
++
++	}
++	else
++	{
++		// Group key - KeyIndex(BIT30==0)
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ Group key +++++\n"));
++
++
++		// when add wep key through add key and didn't assigned encryption type before
++		if((padapter->securitypriv.ndisauthtype<=3)&&(padapter->securitypriv.dot118021XGrpPrivacy==0))
++		{
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("keylen=%d( Adapter->securitypriv.dot11PrivacyAlgrthm=%x  )padapter->securitypriv.dot118021XGrpPrivacy(%x)\n", key->KeyLength,padapter->securitypriv.dot11PrivacyAlgrthm,padapter->securitypriv.dot118021XGrpPrivacy));
++
++			switch(key->KeyLength)
++			{
++				case 5:
++					padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
++					RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
++					break;
++				case 13:
++					padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
++					RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u\n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
++					break;
++				default:
++					padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
++					RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("Adapter->securitypriv.dot11PrivacyAlgrthm= %x key->KeyLength=%u \n", padapter->securitypriv.dot11PrivacyAlgrthm,key->KeyLength));
++					break;
++			}
++
++			encryptionalgo=padapter->securitypriv.dot11PrivacyAlgrthm;
++
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" Adapter->securitypriv.dot11PrivacyAlgrthm=%x\n", padapter->securitypriv.dot11PrivacyAlgrthm));
++
++		}
++		else
++		{
++			encryptionalgo=padapter->securitypriv.dot118021XGrpPrivacy;
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("( Adapter->securitypriv.dot11PrivacyAlgrthm=%x  )encryptionalgo(%x)=padapter->securitypriv.dot118021XGrpPrivacy(%x)keylen=%d\n", padapter->securitypriv.dot11PrivacyAlgrthm,encryptionalgo,padapter->securitypriv.dot118021XGrpPrivacy,key->KeyLength));
++
++		}
++
++		if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE) && (IS_MAC_ADDRESS_BROADCAST(key->BSSID) == _FALSE)) {
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" IBSS but BSSID is not Broadcast Address.\n"));
++			ret= _FAIL;
++			goto exit;
++		}
++
++		// Check key length for TKIP
++		if((encryptionalgo== _TKIP_) && (key->KeyLength != 32)) {
++
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,(" TKIP GTK KeyLength:%u != 32\n", key->KeyLength));
++			ret= _FAIL;
++			goto exit;
++
++		} else if(encryptionalgo== _AES_ && (key->KeyLength != 16 && key->KeyLength != 32) ) {
++
++			// Check key length for AES
++			// For NDTEST, we allow keylen=32 in this case. 2005.01.27, by rcnjko.
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("<=== SetInfo, OID_802_11_ADD_KEY: AES GTK KeyLength:%u != 16 or 32\n", key->KeyLength));
++			ret= _FAIL;
++			goto exit;
++		}
++
++		// Change the key length for EAPPkt9x.vxd. Added by Annie, 2005-11-03.
++		if((encryptionalgo==  _AES_) && (key->KeyLength == 32) ) {
++			key->KeyLength = 16;
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("AES key length changed: %u\n", key->KeyLength) );
++		}
++
++		if(key->KeyIndex & 0x8000000) {//error ??? 0x8000_0000
++			bgrouptkey = _TRUE;
++		}
++
++		if((check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE)==_TRUE)&&(check_fwstate(&padapter->mlmepriv, _FW_LINKED)==_TRUE))
++		{
++			bgrouptkey = _TRUE;
++		}
++
++		bgroup = _TRUE;
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n") );
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("[Group Key set]\n") );
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n")) ;
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key index: 0x%8x(0x%8x)\n", key->KeyIndex,(key->KeyIndex&0x3)));
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("key Length: %d\n", key->KeyLength)) ;
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("------------------------------------------\n"));
++
++	}
++
++	// If WEP encryption algorithm, just call rtw_set_802_11_add_wep().
++	if((padapter->securitypriv.dot11AuthAlgrthm !=dot11AuthAlgrthm_8021X)&&(encryptionalgo== _WEP40_  || encryptionalgo== _WEP104_))
++	{
++		u8 ret;
++		u32 keyindex;
++		u32 len = FIELD_OFFSET(NDIS_802_11_KEY, KeyMaterial) + key->KeyLength;
++		NDIS_802_11_WEP *wep = &padapter->securitypriv.ndiswep;
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ WEP key +++++\n"));
++
++		wep->Length = len;
++		keyindex = key->KeyIndex&0x7fffffff;
++		wep->KeyIndex = keyindex ;
++		wep->KeyLength = key->KeyLength;
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY:Before memcpy \n"));
++
++		_rtw_memcpy(wep->KeyMaterial, key->KeyMaterial, key->KeyLength);
++		_rtw_memcpy(&(padapter->securitypriv.dot11DefKey[keyindex].skey[0]), key->KeyMaterial, key->KeyLength);
++
++		padapter->securitypriv.dot11DefKeylen[keyindex]=key->KeyLength;
++		padapter->securitypriv.dot11PrivacyKeyIndex=keyindex;
++
++		ret = rtw_set_802_11_add_wep(padapter, wep);
++
++		goto exit;
++
++	}
++
++	if(key->KeyIndex & 0x20000000){
++		// SetRSC
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("OID_802_11_ADD_KEY: +++++ SetRSC+++++\n"));
++		if(bgroup == _TRUE)
++		{
++			NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL;
++			_rtw_memcpy(&padapter->securitypriv.dot11Grprxpn, &keysrc, 8);
++		}
++		else
++		{
++			NDIS_802_11_KEY_RSC keysrc=key->KeyRSC & 0x00FFFFFFFFFFFFULL;
++			_rtw_memcpy(&padapter->securitypriv.dot11Grptxpn, &keysrc, 8);
++		}
++
++	}
++
++	// Indicate this key idx is used for TX
++	// Save the key in KeyMaterial
++	if(bgroup == _TRUE) // Group transmit key
++	{
++		int res;
++
++		if(bgrouptkey == _TRUE)
++		{
++			padapter->securitypriv.dot118021XGrpKeyid=(u8)key->KeyIndex;
++		}
++
++		if((key->KeyIndex&0x3) == 0){
++			ret = _FAIL;
++			goto exit;
++		}
++
++		_rtw_memset(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
++		_rtw_memset(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
++		_rtw_memset(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], 0, 16);
++
++		if((key->KeyIndex & 0x10000000))
++		{
++			_rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
++			_rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
++
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
++
++		}
++		else
++		{
++			_rtw_memcpy(&padapter->securitypriv.dot118021XGrptxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 24, 8);
++			_rtw_memcpy(&padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial + 16, 8);
++
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rx mic :0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[0],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[1],
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[2],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[3],
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[4],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[5],
++				padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex) & 0x03)].skey[6],padapter->securitypriv.dot118021XGrprxmickey[(u8)((key->KeyIndex-1) & 0x03)].skey[7]));
++			RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:set Group mic key!!!!!!!!\n"));
++
++		}
++
++		//set group key by index
++		_rtw_memcpy(&padapter->securitypriv.dot118021XGrpKey[(u8)((key->KeyIndex) & 0x03)], key->KeyMaterial, key->KeyLength);
++
++		key->KeyIndex=key->KeyIndex & 0x03;
++
++		padapter->securitypriv.binstallGrpkey=_TRUE;
++
++		padapter->securitypriv.bcheck_grpkey=_FALSE;
++
++		RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key"));
++
++		res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1);
++
++		if(res==_FAIL)
++			ret= _FAIL;
++
++		goto exit;
++
++	}
++	else // Pairwise Key
++	{
++		u8 res;
++
++		pbssid=get_bssid(&padapter->mlmepriv);
++		stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid );
++
++		if(stainfo!=NULL)
++		{
++			_rtw_memset( &stainfo->dot118021x_UncstKey, 0, 16);// clear keybuffer
++
++			_rtw_memcpy(&stainfo->dot118021x_UncstKey, key->KeyMaterial, 16);
++
++			if(encryptionalgo== _TKIP_)
++			{
++				padapter->securitypriv.busetkipkey=_FALSE;
++
++				//_set_timer(&padapter->securitypriv.tkip_timer, 50);
++
++				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n ==========_set_timer\n"));
++
++				// if TKIP, save the Receive/Transmit MIC key in KeyMaterial[128-255]
++				if((key->KeyIndex & 0x10000000)){
++					_rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 16, 8);
++					_rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 24, 8);
++
++				} else {
++					_rtw_memcpy(&stainfo->dot11tkiptxmickey, key->KeyMaterial + 24, 8);
++					_rtw_memcpy(&stainfo->dot11tkiprxmickey, key->KeyMaterial + 16, 8);
++
++				}
++
++			}
++			else if(encryptionalgo == _AES_)
++			{
++
++			}
++
++
++			//Set key to CAM through H2C command
++			if(bgrouptkey)//never go to here
++			{
++				res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE);
++				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n"));
++			}
++			else{
++				res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE);
++				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n"));
++			}
++
++			if(res ==_FALSE)
++				ret= _FAIL;
++
++		}
++
++	}
++
++exit:
++
++_func_exit_;
++
++	return ret;
++}
++
++u8 rtw_set_802_11_remove_key(_adapter*	padapter, NDIS_802_11_REMOVE_KEY *key){
++
++	uint				encryptionalgo;
++	u8 * pbssid;
++	struct sta_info *stainfo;
++	u8	bgroup = (key->KeyIndex & 0x4000000) > 0 ? _FALSE: _TRUE;
++	u8	keyIndex = (u8)key->KeyIndex & 0x03;
++	u8	ret=_SUCCESS;
++
++_func_enter_;
++
++	if ((key->KeyIndex & 0xbffffffc) > 0) {
++		ret=_FAIL;
++		goto exit;
++	}
++
++	if (bgroup == _TRUE) {
++		encryptionalgo= padapter->securitypriv.dot118021XGrpPrivacy;
++		// clear group key by index
++		//NdisZeroMemory(Adapter->MgntInfo.SecurityInfo.KeyBuf[keyIndex], MAX_WEP_KEY_LEN);
++		//Adapter->MgntInfo.SecurityInfo.KeyLen[keyIndex] = 0;
++
++		_rtw_memset(&padapter->securitypriv.dot118021XGrpKey[keyIndex], 0, 16);
++
++		//! \todo Send a H2C Command to Firmware for removing this Key in CAM Entry.
++
++	} else {
++
++		pbssid=get_bssid(&padapter->mlmepriv);
++		stainfo=rtw_get_stainfo(&padapter->stapriv , pbssid );
++		if(stainfo !=NULL){
++			encryptionalgo=stainfo->dot118021XPrivacy;
++
++		// clear key by BSSID
++		_rtw_memset(&stainfo->dot118021x_UncstKey, 0, 16);
++
++		//! \todo Send a H2C Command to Firmware for disable this Key in CAM Entry.
++
++		}
++		else{
++			ret= _FAIL;
++			goto exit;
++		}
++	}
++
++exit:
++
++_func_exit_;
++
++	return _TRUE;
++
++}
++
++/*
++* rtw_get_cur_max_rate -
++* @adapter: pointer to _adapter structure
++*
++* Return 0 or 100Kbps
++*/
++u16 rtw_get_cur_max_rate(_adapter *adapter)
++{
++	int	i = 0;
++	u8	*p;
++	u16	rate = 0, max_rate = 0;
++	struct mlme_ext_priv	*pmlmeext = &adapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct registry_priv *pregistrypriv = &adapter->registrypriv;
++	struct mlme_priv	*pmlmepriv = &adapter->mlmepriv;
++	WLAN_BSSID_EX  *pcur_bss = &pmlmepriv->cur_network.network;
++#ifdef CONFIG_80211N_HT
++	struct rtw_ieee80211_ht_cap *pht_capie;
++	u8	rf_type = 0;
++	u8	bw_40MHz=0, short_GI_20=0, short_GI_40=0;
++	u16	mcs_rate=0;
++	u32	ht_ielen = 0;
++#endif
++
++#ifdef CONFIG_MP_INCLUDED
++	if (adapter->registrypriv.mp_mode == 1)
++	{
++		if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
++			return 0;
++	}
++#endif
++
++	if((check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE)
++		&& (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE))
++		return 0;
++
++#ifdef CONFIG_80211N_HT
++	if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) {
++		p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength-12);
++		if(p && ht_ielen>0)
++		{
++			pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
++
++			_rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
++
++			//bw_40MHz = (pht_capie->cap_info&IEEE80211_HT_CAP_SUP_WIDTH) ? 1:0;
++			//cur_bwmod is updated by beacon, pmlmeinfo is updated by association response
++			bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1:0;
++
++			//short_GI = (pht_capie->cap_info&(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40)) ? 1:0;
++			short_GI_20 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_20) ? 1:0;
++			short_GI_40 = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info&IEEE80211_HT_CAP_SGI_40) ? 1:0;
++
++			rtw_hal_get_hwreg(adapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
++			max_rate = rtw_mcs_rate(
++				rf_type,
++				bw_40MHz & (pregistrypriv->cbw40_enable),
++				short_GI_20,
++				short_GI_40,
++				pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate
++			);
++		}
++	}
++	else
++#endif //CONFIG_80211N_HT
++	{
++		while( (pcur_bss->SupportedRates[i]!=0) && (pcur_bss->SupportedRates[i]!=0xFF))
++		{
++			rate = pcur_bss->SupportedRates[i]&0x7F;
++			if(rate>max_rate)
++				max_rate = rate;
++			i++;
++		}
++
++		max_rate = max_rate*10/2;
++	}
++
++	return max_rate;
++}
++
++/*
++* rtw_set_scan_mode -
++* @adapter: pointer to _adapter structure
++* @scan_mode:
++*
++* Return _SUCCESS or _FAIL
++*/
++int rtw_set_scan_mode(_adapter *adapter, RT_SCAN_TYPE scan_mode)
++{
++	if(scan_mode != SCAN_ACTIVE && scan_mode != SCAN_PASSIVE)
++		return _FAIL;
++
++	adapter->mlmepriv.scan_mode = scan_mode;
++
++	return _SUCCESS;
++}
++
++/*
++* rtw_set_channel_plan -
++* @adapter: pointer to _adapter structure
++* @channel_plan:
++*
++* Return _SUCCESS or _FAIL
++*/
++int rtw_set_channel_plan(_adapter *adapter, u8 channel_plan)
++{
++	struct registry_priv *pregistrypriv = &adapter->registrypriv;
++	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
++
++	//handle by cmd_thread to sync with scan operation
++	return rtw_set_chplan_cmd(adapter, channel_plan, 1);
++}
++
++/*
++* rtw_set_country -
++* @adapter: pointer to _adapter structure
++* @country_code: string of country code
++*
++* Return _SUCCESS or _FAIL
++*/
++int rtw_set_country(_adapter *adapter, const char *country_code)
++{
++	int channel_plan = RT_CHANNEL_DOMAIN_WORLD_WIDE_5G;
++
++	DBG_871X("%s country_code:%s\n", __func__, country_code);
++
++	//TODO: should have a table to match country code and RT_CHANNEL_DOMAIN
++	//TODO: should consider 2-character and 3-character country code
++	if(0 == strcmp(country_code, "US"))
++		channel_plan = RT_CHANNEL_DOMAIN_FCC;
++	else if(0 == strcmp(country_code, "EU"))
++		channel_plan = RT_CHANNEL_DOMAIN_ETSI;
++	else if(0 == strcmp(country_code, "JP"))
++		channel_plan = RT_CHANNEL_DOMAIN_MKK;
++	else if(0 == strcmp(country_code, "CN"))
++		channel_plan = RT_CHANNEL_DOMAIN_CHINA;
++	else
++		DBG_871X("%s unknown country_code:%s\n", __FUNCTION__, country_code);
++
++	return rtw_set_channel_plan(adapter, channel_plan);
++}
++
++/*
++* rtw_set_band -
++* @adapter: pointer to _adapter structure
++* @band: band to set
++*
++* Return _SUCCESS or _FAIL
++*/
++int rtw_set_band(_adapter *adapter, enum _BAND band)
++{
++	if (rtw_band_valid(band)) {
++		DBG_871X(FUNC_ADPT_FMT" band:%d\n", FUNC_ADPT_ARG(adapter), band);
++		adapter->setband = band;
++		return _SUCCESS;
++	}
++
++	DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" band:%d fail\n", FUNC_ADPT_ARG(adapter), band);
++	return _FAIL;
++}
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_iol.c
+@@ -0,0 +1,262 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++
++#include<rtw_iol.h>
++
++#ifdef CONFIG_IOL
++struct xmit_frame	*rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)
++{
++	struct xmit_frame	*xmit_frame;
++	struct xmit_buf	*xmitbuf;
++	struct pkt_attrib	*pattrib;
++	struct xmit_priv	*pxmitpriv = &(adapter->xmitpriv);
++
++#if 1
++	if ((xmit_frame = rtw_alloc_xmitframe(pxmitpriv)) == NULL)
++	{
++		DBG_871X("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);
++		goto exit;
++	}
++
++	if ((xmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL)
++	{
++		DBG_871X("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);
++		rtw_free_xmitframe(pxmitpriv, xmit_frame);
++		xmit_frame=NULL;
++		goto exit;
++	}
++
++	xmit_frame->frame_tag = MGNT_FRAMETAG;
++	xmit_frame->pxmitbuf = xmitbuf;
++	xmit_frame->buf_addr = xmitbuf->pbuf;
++	xmitbuf->priv_data = xmit_frame;
++
++	pattrib = &xmit_frame->attrib;
++	update_mgntframe_attrib(adapter, pattrib);
++	pattrib->qsel = 0x10;
++	pattrib->pktlen = pattrib->last_txcmdsz = 0;
++
++#else
++	if ((xmit_frame = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
++	}
++	else {
++		pattrib = &xmit_frame->attrib;
++		update_mgntframe_attrib(adapter, pattrib);
++		pattrib->qsel = 0x10;
++		pattrib->pktlen = pattrib->last_txcmdsz = 0;
++	}
++#endif
++
++exit:
++	return xmit_frame;
++}
++
++
++int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
++{
++	struct pkt_attrib	*pattrib = &xmit_frame->attrib;
++	u16 buf_offset;
++	u32 ori_len;
++
++//Todo: bulkout without this offset
++#ifdef CONFIG_USB_HCI
++	buf_offset = TXDESC_OFFSET;
++#else
++	buf_offset = 0;
++#endif
++
++	ori_len = buf_offset+pattrib->pktlen;
++
++	//check if the io_buf can accommodate new cmds
++	if(ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
++		DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
++			, ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
++		return _FAIL;
++	}
++
++	_rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
++	pattrib->pktlen += cmd_len;
++	pattrib->last_txcmdsz += cmd_len;
++
++	//DBG_871X("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen);
++
++	return _SUCCESS;
++}
++
++int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
++{
++	IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
++
++	RTW_PUT_BE32((u8*)&cmd.value, (u32)page_boundary);
++
++	return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
++}
++
++int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
++{
++	IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
++
++	RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
++	RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
++
++	return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
++}
++
++int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
++{
++	IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
++
++	RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
++	RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
++
++	return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
++}
++
++int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
++{
++	IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
++	u8* pos = (u8 *)&cmd;
++
++	RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
++	RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
++
++	return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
++}
++
++#ifdef DBG_IO
++int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, 1))
++		DBG_871X("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value);
++
++	return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
++}
++
++int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, 2))
++		DBG_871X("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value);
++
++	return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
++}
++
++int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
++{
++	if (match_write_sniff_ranges(addr, 4))
++		DBG_871X("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value);
++
++	return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
++}
++#endif
++
++int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
++{
++	IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
++
++	RTW_PUT_BE32((u8*)&cmd.value, (u32)us);
++
++	//DBG_871X("%s %u\n", __FUNCTION__, us);
++
++	return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
++}
++
++int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
++{
++	IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
++
++	RTW_PUT_BE32((u8*)&cmd.value, (u32)ms);
++
++	//DBG_871X("%s %u\n", __FUNCTION__, ms);
++
++	return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
++}
++
++int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
++{
++	struct pkt_attrib	*pattrib = &xmit_frame->attrib;
++	u16 buf_offset;
++	u32 ori_len;
++	IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
++
++//Todo: bulkout without this offset
++#ifdef CONFIG_USB_HCI
++	buf_offset = TXDESC_OFFSET;
++#else
++	buf_offset = 0;
++#endif
++
++	ori_len = buf_offset+pattrib->pktlen;
++
++	//check if the io_buf can accommodate new cmds
++	if(ori_len + 8 > MAX_XMITBUF_SZ) {
++		DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate end cmd\n", __FUNCTION__
++			, ori_len + 8, MAX_XMITBUF_SZ);
++		return _FAIL;
++	}
++
++	_rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, (u8*)&end_cmd, 8);
++	pattrib->pktlen += 8;
++	pattrib->last_txcmdsz += 8;
++
++	//DBG_871X("%s ori:%u + 8 = %u\n", __FUNCTION__ , ori_len, buf_offset+pattrib->pktlen);
++
++	return _SUCCESS;
++}
++
++int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms)
++{
++	return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms);
++}
++
++int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
++{
++	struct xmit_frame	*xmit_frame;
++
++	if((xmit_frame=rtw_IOL_accquire_xmit_frame(adapter)) == NULL)
++		return _FAIL;
++
++	if(rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num<<3) == _FAIL)
++		return _FAIL;
++
++	return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms);
++}
++
++int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
++{
++	IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
++	return rtw_IOL_exec_cmd_array_sync(adapter, (u8*)&end_cmd, 1, max_wating_ms);
++}
++
++bool rtw_IOL_applied(ADAPTER *adapter)
++{
++	if(adapter->registrypriv.force_iol)
++		return _TRUE;
++
++#ifdef CONFIG_USB_HCI
++	if(!adapter_to_dvobj(adapter)->ishighspeed)
++		return _TRUE;
++#endif
++
++	return _FALSE;
++}
++
++#endif //CONFIG_IOL
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_mlme.c
+@@ -0,0 +1,3966 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_MLME_C_
++
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <recv_osdep.h>
++#include <xmit_osdep.h>
++#include <hal_intf.h>
++#include <mlme_osdep.h>
++#include <sta_info.h>
++#include <wifi.h>
++#include <wlan_bssdef.h>
++#include <rtw_ioctl_set.h>
++
++extern void indicate_wx_scan_complete_event(_adapter *padapter);
++extern u8 rtw_do_join(_adapter * padapter);
++
++#ifdef CONFIG_DISABLE_MCS13TO15
++extern unsigned char	MCS_rate_2R_MCS13TO15_OFF[16];
++extern unsigned char	MCS_rate_2R[16];
++#else //CONFIG_DISABLE_MCS13TO15
++extern unsigned char	MCS_rate_2R[16];
++#endif //CONFIG_DISABLE_MCS13TO15
++extern unsigned char	MCS_rate_1R[16];
++
++sint	_rtw_init_mlme_priv (_adapter* padapter)
++{
++	sint	i;
++	u8	*pbuf;
++	struct wlan_network	*pnetwork;
++	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
++	sint	res = _SUCCESS;
++
++_func_enter_;
++
++	// We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
++	//_rtw_memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv));
++
++	pmlmepriv->nic_hdl = (u8 *)padapter;
++
++	pmlmepriv->pscanned = NULL;
++	pmlmepriv->fw_state = 0;
++	pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
++	pmlmepriv->scan_mode=SCAN_ACTIVE;// 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff)
++
++	_rtw_spinlock_init(&(pmlmepriv->lock));
++	_rtw_init_queue(&(pmlmepriv->free_bss_pool));
++	_rtw_init_queue(&(pmlmepriv->scanned_queue));
++
++	set_scanned_network_val(pmlmepriv, 0);
++
++	_rtw_memset(&pmlmepriv->assoc_ssid,0,sizeof(NDIS_802_11_SSID));
++
++	pbuf = rtw_zvmalloc(MAX_BSS_CNT * (sizeof(struct wlan_network)));
++
++	if (pbuf == NULL){
++		res=_FAIL;
++		goto exit;
++	}
++	pmlmepriv->free_bss_buf = pbuf;
++
++	pnetwork = (struct wlan_network *)pbuf;
++
++	for(i = 0; i < MAX_BSS_CNT; i++)
++	{
++		_rtw_init_listhead(&(pnetwork->list));
++
++		rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
++
++		pnetwork++;
++	}
++
++	//allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf
++
++	rtw_clear_scan_deny(padapter);
++
++	rtw_init_mlme_timer(padapter);
++
++exit:
++
++_func_exit_;
++
++	return res;
++}
++
++void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv);
++void rtw_mfree_mlme_priv_lock (struct mlme_priv *pmlmepriv)
++{
++	_rtw_spinlock_free(&pmlmepriv->lock);
++	_rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock));
++	_rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock));
++}
++
++static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
++{
++	if(*ppie)
++	{
++		rtw_mfree(*ppie, *plen);
++		*plen = 0;
++		*ppie=NULL;
++	}
++}
++
++void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
++{
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
++	rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
++
++	rtw_free_mlme_ie_data(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
++#endif
++
++#if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
++	rtw_free_mlme_ie_data(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len);
++	rtw_free_mlme_ie_data(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
++#endif
++
++}
++
++void _rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
++{
++_func_enter_;
++
++	rtw_free_mlme_priv_ie_data(pmlmepriv);
++
++	if(pmlmepriv){
++		rtw_mfree_mlme_priv_lock (pmlmepriv);
++
++		if (pmlmepriv->free_bss_buf) {
++			rtw_vmfree(pmlmepriv->free_bss_buf, MAX_BSS_CNT * sizeof(struct wlan_network));
++		}
++	}
++_func_exit_;
++}
++
++sint	_rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
++{
++	_irqL irqL;
++
++_func_enter_;
++
++	if (pnetwork == NULL)
++		goto exit;
++
++	_enter_critical_bh(&queue->lock, &irqL);
++
++	rtw_list_insert_tail(&pnetwork->list, &queue->queue);
++
++	_exit_critical_bh(&queue->lock, &irqL);
++
++exit:
++
++_func_exit_;
++
++	return _SUCCESS;
++}
++
++struct	wlan_network *_rtw_dequeue_network(_queue *queue)
++{
++	_irqL irqL;
++
++	struct wlan_network *pnetwork;
++
++_func_enter_;
++
++	_enter_critical_bh(&queue->lock, &irqL);
++
++	if (_rtw_queue_empty(queue) == _TRUE)
++
++		pnetwork = NULL;
++
++	else
++	{
++		pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list);
++
++		rtw_list_delete(&(pnetwork->list));
++	}
++
++	_exit_critical_bh(&queue->lock, &irqL);
++
++_func_exit_;
++
++	return pnetwork;
++}
++
++struct	wlan_network *_rtw_alloc_network(struct	mlme_priv *pmlmepriv )//(_queue *free_queue)
++{
++	_irqL	irqL;
++	struct	wlan_network	*pnetwork;
++	_queue *free_queue = &pmlmepriv->free_bss_pool;
++	_list* plist = NULL;
++
++_func_enter_;
++
++	_enter_critical_bh(&free_queue->lock, &irqL);
++
++	if (_rtw_queue_empty(free_queue) == _TRUE) {
++		pnetwork=NULL;
++		goto exit;
++	}
++	plist = get_next(&(free_queue->queue));
++
++	pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
++
++	rtw_list_delete(&pnetwork->list);
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("_rtw_alloc_network: ptr=%p\n", plist));
++	pnetwork->network_type = 0;
++	pnetwork->fixed = _FALSE;
++	pnetwork->last_scanned = rtw_get_current_time();
++	pnetwork->aid=0;
++	pnetwork->join_res=0;
++
++	pmlmepriv->num_of_scanned ++;
++
++exit:
++	_exit_critical_bh(&free_queue->lock, &irqL);
++
++_func_exit_;
++
++	return pnetwork;
++}
++
++void _rtw_free_network(struct	mlme_priv *pmlmepriv ,struct wlan_network *pnetwork, u8 isfreeall)
++{
++	u32 curr_time, delta_time;
++	u32 lifetime = SCANQUEUE_LIFETIME;
++	_irqL irqL;
++	_queue *free_queue = &(pmlmepriv->free_bss_pool);
++
++_func_enter_;
++
++	if (pnetwork == NULL)
++		goto exit;
++
++	if (pnetwork->fixed == _TRUE)
++		goto exit;
++
++	curr_time = rtw_get_current_time();
++
++	if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) ||
++		(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
++		lifetime = 1;
++
++	if(!isfreeall)
++	{
++#ifdef PLATFORM_WINDOWS
++
++		delta_time = (curr_time -pnetwork->last_scanned)/10;
++
++		if(delta_time  < lifetime*1000000)// unit:usec
++		{
++			goto exit;
++		}
++
++#endif
++
++#ifdef PLATFORM_LINUX
++
++		delta_time = (curr_time -pnetwork->last_scanned)/HZ;
++
++		if(delta_time < lifetime)// unit:sec
++		{
++			goto exit;
++		}
++
++#endif
++
++#ifdef PLATFORM_FREEBSD
++        //i think needs to check again
++		delta_time = (curr_time -pnetwork->last_scanned)/hz;
++
++		if(delta_time < lifetime)// unit:sec
++		{
++			goto exit;
++		}
++
++#endif
++	}
++
++	_enter_critical_bh(&free_queue->lock, &irqL);
++
++	rtw_list_delete(&(pnetwork->list));
++
++	rtw_list_insert_tail(&(pnetwork->list),&(free_queue->queue));
++
++	pmlmepriv->num_of_scanned --;
++
++
++	//DBG_871X("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid);
++
++	_exit_critical_bh(&free_queue->lock, &irqL);
++
++exit:
++
++_func_exit_;
++
++}
++
++void _rtw_free_network_nolock(struct	mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
++{
++
++	_queue *free_queue = &(pmlmepriv->free_bss_pool);
++
++_func_enter_;
++
++	if (pnetwork == NULL)
++		goto exit;
++
++	if (pnetwork->fixed == _TRUE)
++		goto exit;
++
++	//_enter_critical(&free_queue->lock, &irqL);
++
++	rtw_list_delete(&(pnetwork->list));
++
++	rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue));
++
++	pmlmepriv->num_of_scanned --;
++
++	//_exit_critical(&free_queue->lock, &irqL);
++
++exit:
++
++_func_exit_;
++
++}
++
++
++/*
++	return the wlan_network with the matching addr
++
++	Shall be calle under atomic context... to avoid possible racing condition...
++*/
++struct wlan_network *_rtw_find_network(_queue *scanned_queue, u8 *addr)
++{
++
++	//_irqL irqL;
++	_list	*phead, *plist;
++	struct	wlan_network *pnetwork = NULL;
++	u8 zero_addr[ETH_ALEN] = {0,0,0,0,0,0};
++
++_func_enter_;
++
++	if(_rtw_memcmp(zero_addr, addr, ETH_ALEN)){
++		pnetwork=NULL;
++		goto exit;
++	}
++
++	//_enter_critical_bh(&scanned_queue->lock, &irqL);
++
++	phead = get_list_head(scanned_queue);
++	plist = get_next(phead);
++
++	while (plist != phead)
++       {
++                pnetwork = LIST_CONTAINOR(plist, struct wlan_network ,list);
++
++		if (_rtw_memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)
++                        break;
++
++		plist = get_next(plist);
++        }
++
++	if(plist == phead)
++		pnetwork = NULL;
++
++	//_exit_critical_bh(&scanned_queue->lock, &irqL);
++
++exit:
++
++_func_exit_;
++
++	return pnetwork;
++
++}
++
++
++void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall)
++{
++	_irqL irqL;
++	_list *phead, *plist;
++	struct wlan_network *pnetwork;
++	struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
++	_queue *scanned_queue = &pmlmepriv->scanned_queue;
++
++_func_enter_;
++
++
++	_enter_critical_bh(&scanned_queue->lock, &irqL);
++
++	phead = get_list_head(scanned_queue);
++	plist = get_next(phead);
++
++	while (rtw_end_of_queue_search(phead, plist) == _FALSE)
++	{
++
++		pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
++
++		plist = get_next(plist);
++
++		_rtw_free_network(pmlmepriv,pnetwork, isfreeall);
++
++	}
++
++	_exit_critical_bh(&scanned_queue->lock, &irqL);
++
++_func_exit_;
++
++}
++
++
++
++
++sint rtw_if_up(_adapter *padapter)	{
++
++	sint res;
++_func_enter_;
++
++	if( padapter->bDriverStopped || padapter->bSurpriseRemoved ||
++		(check_fwstate(&padapter->mlmepriv, _FW_LINKED)== _FALSE)){
++		RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("rtw_if_up:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
++		res=_FALSE;
++	}
++	else
++		res=  _TRUE;
++
++_func_exit_;
++	return res;
++}
++
++
++void rtw_generate_random_ibss(u8* pibss)
++{
++	u32	curtime = rtw_get_current_time();
++
++_func_enter_;
++	pibss[0] = 0x02;  //in ad-hoc mode bit1 must set to 1
++	pibss[1] = 0x11;
++	pibss[2] = 0x87;
++	pibss[3] = (u8)(curtime & 0xff) ;//p[0];
++	pibss[4] = (u8)((curtime>>8) & 0xff) ;//p[1];
++	pibss[5] = (u8)((curtime>>16) & 0xff) ;//p[2];
++_func_exit_;
++	return;
++}
++
++u8 *rtw_get_capability_from_ie(u8 *ie)
++{
++	return (ie + 8 + 2);
++}
++
++
++u16 rtw_get_capability(WLAN_BSSID_EX *bss)
++{
++	u16	val;
++_func_enter_;
++
++	_rtw_memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2);
++
++_func_exit_;
++	return le16_to_cpu(val);
++}
++
++u8 *rtw_get_timestampe_from_ie(u8 *ie)
++{
++	return (ie + 0);
++}
++
++u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
++{
++	return (ie + 8);
++}
++
++
++int	rtw_init_mlme_priv (_adapter *padapter)//(struct	mlme_priv *pmlmepriv)
++{
++	int	res;
++_func_enter_;
++	res = _rtw_init_mlme_priv(padapter);// (pmlmepriv);
++_func_exit_;
++	return res;
++}
++
++void rtw_free_mlme_priv (struct mlme_priv *pmlmepriv)
++{
++_func_enter_;
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_mlme_priv\n"));
++	_rtw_free_mlme_priv (pmlmepriv);
++_func_exit_;
++}
++
++int	rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork);
++int	rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
++{
++	int	res;
++_func_enter_;
++	res = _rtw_enqueue_network(queue, pnetwork);
++_func_exit_;
++	return res;
++}
++
++
++#ifndef PLATFORM_FREEBSD //Baron
++static struct	wlan_network *rtw_dequeue_network(_queue *queue)
++{
++	struct wlan_network *pnetwork;
++_func_enter_;
++	pnetwork = _rtw_dequeue_network(queue);
++_func_exit_;
++	return pnetwork;
++}
++#endif //PLATFORM_FREEBSD
++
++struct	wlan_network *rtw_alloc_network(struct	mlme_priv *pmlmepriv );
++struct	wlan_network *rtw_alloc_network(struct	mlme_priv *pmlmepriv )//(_queue	*free_queue)
++{
++	struct	wlan_network	*pnetwork;
++_func_enter_;
++	pnetwork = _rtw_alloc_network(pmlmepriv);
++_func_exit_;
++	return pnetwork;
++}
++
++void rtw_free_network(struct mlme_priv *pmlmepriv, struct	wlan_network *pnetwork, u8 is_freeall);
++void rtw_free_network(struct mlme_priv *pmlmepriv, struct	wlan_network *pnetwork, u8 is_freeall)//(struct	wlan_network *pnetwork, _queue	*free_queue)
++{
++_func_enter_;
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid));
++	_rtw_free_network(pmlmepriv, pnetwork, is_freeall);
++_func_exit_;
++}
++
++void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork );
++void rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork )
++{
++_func_enter_;
++	//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_network==> ssid = %s \n\n" , pnetwork->network.Ssid.Ssid));
++	_rtw_free_network_nolock(pmlmepriv, pnetwork);
++_func_exit_;
++}
++
++
++void rtw_free_network_queue(_adapter* dev, u8 isfreeall)
++{
++_func_enter_;
++	_rtw_free_network_queue(dev, isfreeall);
++_func_exit_;
++}
++
++/*
++	return the wlan_network with the matching addr
++
++	Shall be calle under atomic context... to avoid possible racing condition...
++*/
++struct	wlan_network *rtw_find_network(_queue *scanned_queue, u8 *addr)
++{
++	struct	wlan_network *pnetwork = _rtw_find_network(scanned_queue, addr);
++
++	return pnetwork;
++}
++
++int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork)
++{
++	int ret=_TRUE;
++	struct security_priv *psecuritypriv = &adapter->securitypriv;
++
++	if ( (psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ ) &&
++		    ( pnetwork->network.Privacy == 0 ) )
++	{
++		ret=_FALSE;
++	}
++	else if((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_ ) &&
++		 ( pnetwork->network.Privacy == 1 ) )
++	{
++		ret=_FALSE;
++	}
++	else
++	{
++		ret=_TRUE;
++	}
++
++	return ret;
++
++}
++
++inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b);
++inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
++{
++	//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(%s,%d)(%s,%d)\n",
++	//		a->Ssid.Ssid,a->Ssid.SsidLength,b->Ssid.Ssid,b->Ssid.SsidLength));
++	return (a->Ssid.SsidLength == b->Ssid.SsidLength)
++		&&  _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength)==_TRUE;
++}
++
++int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst)
++{
++	 u16 s_cap, d_cap;
++
++_func_enter_;
++
++#ifdef PLATFORM_OS_XP
++	 if ( ((uint)dst) <= 0x7fffffff ||
++		((uint)src) <= 0x7fffffff ||
++		((uint)&s_cap) <= 0x7fffffff ||
++		((uint)&d_cap) <= 0x7fffffff)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n@@@@ error address of dst\n"));
++
++		KeBugCheckEx(0x87110000, (ULONG_PTR)dst, (ULONG_PTR)src,(ULONG_PTR)&s_cap, (ULONG_PTR)&d_cap);
++
++		return _FALSE;
++	}
++#endif
++
++
++	_rtw_memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2);
++	_rtw_memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2);
++
++
++	s_cap = le16_to_cpu(s_cap);
++	d_cap = le16_to_cpu(d_cap);
++
++_func_exit_;
++
++	return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
++		//	(src->Configuration.DSConfig == dst->Configuration.DSConfig) &&
++			( (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) &&
++			( (_rtw_memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == _TRUE) &&
++			((s_cap & WLAN_CAPABILITY_IBSS) ==
++			(d_cap & WLAN_CAPABILITY_IBSS)) &&
++			((s_cap & WLAN_CAPABILITY_BSS) ==
++			(d_cap & WLAN_CAPABILITY_BSS)));
++
++}
++
++struct	wlan_network	* rtw_get_oldest_wlan_network(_queue *scanned_queue)
++{
++	_list	*plist, *phead;
++
++
++	struct	wlan_network	*pwlan = NULL;
++	struct	wlan_network	*oldest = NULL;
++_func_enter_;
++	phead = get_list_head(scanned_queue);
++
++	plist = get_next(phead);
++
++	while(1)
++	{
++
++		if (rtw_end_of_queue_search(phead,plist)== _TRUE)
++			break;
++
++		pwlan= LIST_CONTAINOR(plist, struct wlan_network, list);
++
++		if(pwlan->fixed!=_TRUE)
++		{
++			if (oldest == NULL ||time_after(oldest->last_scanned, pwlan->last_scanned))
++				oldest = pwlan;
++		}
++
++		plist = get_next(plist);
++	}
++_func_exit_;
++	return oldest;
++
++}
++
++static void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src,
++	_adapter * padapter, bool update_ie)
++{
++	u8 ss_ori = dst->PhyInfo.SignalStrength;
++	u8 sq_ori = dst->PhyInfo.SignalQuality;
++	long rssi_ori = dst->Rssi;
++
++	u8 ss_smp = src->PhyInfo.SignalStrength;
++	u8 sq_smp = src->PhyInfo.SignalQuality;
++	long rssi_smp = src->Rssi;
++
++	u8 ss_final;
++	u8 sq_final;
++	long rssi_final;
++
++_func_enter_;
++
++#ifdef CONFIG_ANTENNA_DIVERSITY
++	rtw_hal_antdiv_rssi_compared(padapter, dst, src); //this will update src.Rssi, need consider again
++#endif
++
++	#if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
++	if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
++		DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
++			, FUNC_ADPT_ARG(padapter)
++			, src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig
++			,ss_ori, sq_ori, rssi_ori
++			,ss_smp, sq_smp, rssi_smp
++		);
++	}
++	#endif
++
++	/* The rule below is 1/5 for sample value, 4/5 for history value */
++	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
++		/* Take the recvpriv's value for the connected AP*/
++		ss_final = padapter->recvpriv.signal_strength;
++		sq_final = padapter->recvpriv.signal_qual;
++		/* the rssi value here is undecorated, and will be used for antenna diversity */
++		if(sq_smp != 101) /* from the right channel */
++			rssi_final = (src->Rssi+dst->Rssi*4)/5;
++		else
++			rssi_final = rssi_ori;
++	}
++	else {
++		if(sq_smp != 101) { /* from the right channel */
++			ss_final = ((u32)(src->PhyInfo.SignalStrength)+(u32)(dst->PhyInfo.SignalStrength)*4)/5;
++			sq_final = ((u32)(src->PhyInfo.SignalQuality)+(u32)(dst->PhyInfo.SignalQuality)*4)/5;
++			rssi_final = (src->Rssi+dst->Rssi*4)/5;
++		} else {
++			/* bss info not receving from the right channel, use the original RX signal infos */
++			ss_final = dst->PhyInfo.SignalStrength;
++			sq_final = dst->PhyInfo.SignalQuality;
++			rssi_final = dst->Rssi;
++		}
++
++	}
++
++	if (update_ie)
++		_rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src));
++
++	dst->PhyInfo.SignalStrength = ss_final;
++	dst->PhyInfo.SignalQuality = sq_final;
++	dst->Rssi = rssi_final;
++
++	#if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
++	if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
++		DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
++			, FUNC_ADPT_ARG(padapter)
++			, dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi);
++	}
++	#endif
++
++#if 0 // old codes, may be useful one day...
++//	DBG_871X("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi);
++	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src))
++	{
++
++		//DBG_871X("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal);
++		if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX)
++	        {
++	              padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
++	              last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
++	              padapter->recvpriv.signal_qual_data.total_val -= last_evm;
++	        }
++		padapter->recvpriv.signal_qual_data.total_val += query_rx_pwr_percentage(src->Rssi);
++
++		padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = query_rx_pwr_percentage(src->Rssi);
++                if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
++                       padapter->recvpriv.signal_qual_data.index = 0;
++
++		//DBG_871X("Total SQ=%d  pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, src->Rssi);
++
++		// <1> Showed on UI for user,in percentage.
++		tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num;
++                padapter->recvpriv.signal=(u8)tmpVal;//Link quality
++
++		src->Rssi= translate_percentage_to_dbm(padapter->recvpriv.signal) ;
++	}
++	else{
++//	DBG_871X("ELSE:ssid=%s update_network: src->rssi=0x%d dst->rssi=%d\n",src->Ssid.Ssid,src->Rssi,dst->Rssi);
++		src->Rssi=(src->Rssi +dst->Rssi)/2;//dBM
++	}
++
++//	DBG_871X("a:update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Rssi,padapter->recvpriv.signal);
++
++#endif
++
++_func_exit_;
++}
++
++static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
++{
++	struct	mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++
++_func_enter_;
++
++#ifdef PLATFORM_OS_XP
++	if ((unsigned long)(&(pmlmepriv->cur_network.network)) < 0x7ffffff)
++	{
++		KeBugCheckEx(0x87111c1c, (ULONG_PTR)(&(pmlmepriv->cur_network.network)), 0, 0,0);
++	}
++#endif
++
++	if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)))
++	{
++		//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n");
++
++		//if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength)
++		{
++			update_network(&(pmlmepriv->cur_network.network), pnetwork,adapter, _TRUE);
++			rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof (NDIS_802_11_FIXED_IEs),
++									pmlmepriv->cur_network.network.IELength);
++		}
++	}
++
++_func_exit_;
++
++}
++
++
++/*
++
++Caller must hold pmlmepriv->lock first.
++
++
++*/
++void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
++{
++	_irqL irqL;
++	_list	*plist, *phead;
++	ULONG	bssid_ex_sz;
++	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++	_queue	*queue	= &(pmlmepriv->scanned_queue);
++	struct wlan_network	*pnetwork = NULL;
++	struct wlan_network	*oldest = NULL;
++
++_func_enter_;
++
++	_enter_critical_bh(&queue->lock, &irqL);
++	phead = get_list_head(queue);
++	plist = get_next(phead);
++
++	while(1)
++	{
++		if (rtw_end_of_queue_search(phead,plist)== _TRUE)
++			break;
++
++		pnetwork	= LIST_CONTAINOR(plist, struct wlan_network, list);
++
++		if ((unsigned long)(pnetwork) < 0x7ffffff)
++		{
++#ifdef PLATFORM_OS_XP
++			KeBugCheckEx(0x87111c1c, (ULONG_PTR)pnetwork, 0, 0,0);
++#endif
++		}
++
++		if (is_same_network(&(pnetwork->network), target))
++			break;
++
++		if ((oldest == ((struct wlan_network *)0)) ||
++		time_after(oldest->last_scanned, pnetwork->last_scanned))
++			oldest = pnetwork;
++
++		plist = get_next(plist);
++
++	}
++
++
++	/* If we didn't find a match, then get a new network slot to initialize
++	 * with this beacon's information */
++	if (rtw_end_of_queue_search(phead,plist)== _TRUE) {
++
++		if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
++			/* If there are no more slots, expire the oldest */
++			//list_del_init(&oldest->list);
++			pnetwork = oldest;
++
++#ifdef CONFIG_ANTENNA_DIVERSITY
++			//target->PhyInfo.Optimum_antenna = pHalData->CurAntenna;//optimum_antenna=>For antenna diversity
++			rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna));
++#endif
++			_rtw_memcpy(&(pnetwork->network), target,  get_WLAN_BSSID_EX_sz(target));
++			//pnetwork->last_scanned = rtw_get_current_time();
++			// variable initialize
++			pnetwork->fixed = _FALSE;
++			pnetwork->last_scanned = rtw_get_current_time();
++
++			pnetwork->network_type = 0;
++			pnetwork->aid=0;
++			pnetwork->join_res=0;
++
++			/* bss info not receving from the right channel */
++			if (pnetwork->network.PhyInfo.SignalQuality == 101)
++				pnetwork->network.PhyInfo.SignalQuality = 0;
++		}
++		else {
++			/* Otherwise just pull from the free list */
++
++			pnetwork = rtw_alloc_network(pmlmepriv); // will update scan_time
++
++			if(pnetwork==NULL){
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n\nsomething wrong here\n\n\n"));
++				goto exit;
++			}
++
++			bssid_ex_sz = get_WLAN_BSSID_EX_sz(target);
++			target->Length = bssid_ex_sz;
++#ifdef CONFIG_ANTENNA_DIVERSITY
++			//target->PhyInfo.Optimum_antenna = pHalData->CurAntenna;
++			rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(target->PhyInfo.Optimum_antenna));
++#endif
++			_rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz );
++
++			pnetwork->last_scanned = rtw_get_current_time();
++
++			/* bss info not receving from the right channel */
++			if (pnetwork->network.PhyInfo.SignalQuality == 101)
++				pnetwork->network.PhyInfo.SignalQuality = 0;
++
++			rtw_list_insert_tail(&(pnetwork->list),&(queue->queue));
++
++		}
++	}
++	else {
++		/* we have an entry and we are going to update it. But this entry may
++		 * be already expired. In this case we do the same as we found a new
++		 * net and call the new_net handler
++		 */
++		bool update_ie = _TRUE;
++
++		pnetwork->last_scanned = rtw_get_current_time();
++
++		//target.Reserved[0]==1, means that scaned network is a bcn frame.
++		if((pnetwork->network.IELength>target->IELength) && (target->Reserved[0]==1))
++			update_ie = _FALSE;
++
++		update_network(&(pnetwork->network), target,adapter, update_ie);
++	}
++
++exit:
++	_exit_critical_bh(&queue->lock, &irqL);
++
++_func_exit_;
++}
++
++void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork);
++void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
++{
++	_irqL irqL;
++	struct	mlme_priv	*pmlmepriv = &(((_adapter *)adapter)->mlmepriv);
++	//_queue	*queue	= &(pmlmepriv->scanned_queue);
++
++_func_enter_;
++
++	//_enter_critical_bh(&queue->lock, &irqL);
++
++	#if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
++	rtw_WLAN_BSSID_EX_remove_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
++	#endif
++
++	update_current_network(adapter, pnetwork);
++
++	rtw_update_scanned_network(adapter, pnetwork);
++
++	//_exit_critical_bh(&queue->lock, &irqL);
++
++_func_exit_;
++}
++
++//select the desired network based on the capability of the (i)bss.
++// check items: (1) security
++//			   (2) network_type
++//			   (3) WMM
++//			   (4) HT
++//                     (5) others
++int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
++int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork)
++{
++	struct security_priv *psecuritypriv = &adapter->securitypriv;
++	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
++	u32 desired_encmode;
++	u32 privacy;
++
++	//u8 wps_ie[512];
++	uint wps_ielen;
++
++	int bselected = _TRUE;
++
++	desired_encmode = psecuritypriv->ndisencryptstatus;
++	privacy = pnetwork->network.Privacy;
++
++	if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
++	{
++		if(rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen)!=NULL)
++		{
++			return _TRUE;
++		}
++		else
++		{
++			return _FALSE;
++		}
++	}
++	if (adapter->registrypriv.wifi_spec == 1) //for  correct flow of 8021X  to do....
++	{
++		u8 *p=NULL;
++		uint ie_len=0;
++
++		if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
++	            bselected = _FALSE;
++
++		if ( psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
++			p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
++			if (p && ie_len>0) {
++				bselected = _TRUE;
++			} else {
++				bselected = _FALSE;
++			}
++		}
++	}
++
++
++	if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) {
++		DBG_871X("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy);
++		bselected = _FALSE;
++	}
++
++	if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)
++	{
++		if(pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
++			bselected = _FALSE;
++	}
++
++
++	return bselected;
++}
++
++/* TODO: Perry : For Power Management */
++void rtw_atimdone_event_callback(_adapter	*adapter , u8 *pbuf)
++{
++
++_func_enter_;
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("receive atimdone_evet\n"));
++_func_exit_;
++	return;
++}
++
++
++void rtw_survey_event_callback(_adapter	*adapter, u8 *pbuf)
++{
++	_irqL  irqL;
++	u32 len;
++	WLAN_BSSID_EX *pnetwork;
++	struct	mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++
++_func_enter_;
++
++	pnetwork = (WLAN_BSSID_EX *)pbuf;
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_survey_event_callback, ssid=%s\n",  pnetwork->Ssid.Ssid));
++
++#ifdef CONFIG_RTL8712
++        //endian_convert
++	pnetwork->Length = le32_to_cpu(pnetwork->Length);
++	pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
++	pnetwork->Privacy =le32_to_cpu( pnetwork->Privacy);
++	pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
++	pnetwork->NetworkTypeInUse =le32_to_cpu(pnetwork->NetworkTypeInUse);
++	pnetwork->Configuration.ATIMWindow = le32_to_cpu(pnetwork->Configuration.ATIMWindow);
++	pnetwork->Configuration.BeaconPeriod = le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
++	pnetwork->Configuration.DSConfig =le32_to_cpu(pnetwork->Configuration.DSConfig);
++	pnetwork->Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
++	pnetwork->Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
++	pnetwork->Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
++	pnetwork->Configuration.FHConfig.Length=le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
++	pnetwork->Configuration.Length = le32_to_cpu(pnetwork->Configuration.Length);
++	pnetwork->InfrastructureMode = le32_to_cpu(pnetwork->InfrastructureMode);
++	pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
++#endif
++
++	len = get_WLAN_BSSID_EX_sz(pnetwork);
++	if(len > (sizeof(WLAN_BSSID_EX)))
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n ****rtw_survey_event_callback: return a wrong bss ***\n"));
++		return;
++	}
++
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	// update IBSS_network 's timestamp
++	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE)
++	{
++		//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"rtw_survey_event_callback : WIFI_ADHOC_MASTER_STATE \n\n");
++		if(_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN))
++		{
++			struct wlan_network* ibss_wlan = NULL;
++			_irqL	irqL;
++
++			_rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
++			_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			ibss_wlan = rtw_find_network(&pmlmepriv->scanned_queue,  pnetwork->MacAddress);
++			if(ibss_wlan)
++			{
++				_rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);
++				_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++				goto exit;
++			}
++			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		}
++	}
++
++	// lock pmlmepriv->lock when you accessing network_q
++	if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _FALSE)
++	{
++	        if( pnetwork->Ssid.Ssid[0] == 0 )
++		{
++			pnetwork->Ssid.SsidLength = 0;
++		}
++		rtw_add_network(adapter, pnetwork);
++	}
++
++exit:
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++_func_exit_;
++
++	return;
++}
++
++
++
++void rtw_surveydone_event_callback(_adapter	*adapter, u8 *pbuf)
++{
++	_irqL  irqL;
++	u8 timer_cancelled = _FALSE;
++	struct	mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++
++#ifdef CONFIG_MLME_EXT
++
++	mlmeext_surveydone_event_callback(adapter);
++
++#endif
++
++_func_enter_;
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++	if(pmlmepriv->wps_probe_req_ie)
++	{
++		u32 free_len = pmlmepriv->wps_probe_req_ie_len;
++		pmlmepriv->wps_probe_req_ie_len = 0;
++		rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
++		pmlmepriv->wps_probe_req_ie = NULL;
++	}
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("rtw_surveydone_event_callback: fw_state:%x\n\n", get_fwstate(pmlmepriv)));
++
++	if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY))
++	{
++		//u8 timer_cancelled;
++
++		timer_cancelled = _TRUE;
++		//_cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
++
++		_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
++	}
++	else {
++
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("nic status =%x, survey done event comes too late!\n", get_fwstate(pmlmepriv)));
++	}
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++	if(timer_cancelled)
++		_cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
++
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
++	rtw_set_signal_stat_timer(&adapter->recvpriv);
++	#endif
++
++	if(pmlmepriv->to_join == _TRUE)
++	{
++		if((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE) )
++		{
++			if(check_fwstate(pmlmepriv, _FW_LINKED)==_FALSE)
++			{
++				set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
++
++				if(rtw_select_and_join_from_scanned_queue(pmlmepriv)==_SUCCESS)
++				{
++					_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT );
++				}
++				else
++				{
++					WLAN_BSSID_EX    *pdev_network = &(adapter->registrypriv.dev_network);
++					u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
++
++					//pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;//because don't set assoc_timer
++					_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
++
++					RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("switching to adhoc master\n"));
++
++					_rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
++					_rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
++
++					rtw_update_registrypriv_dev_network(adapter);
++					rtw_generate_random_ibss(pibss);
++
++					pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
++
++					if(rtw_createbss_cmd(adapter)!=_SUCCESS)
++					{
++					RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Error=>rtw_createbss_cmd status FAIL\n"));
++					}
++
++					pmlmepriv->to_join = _FALSE;
++				}
++			}
++		}
++		else
++		{
++			int s_ret;
++			set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
++			pmlmepriv->to_join = _FALSE;
++			if(_SUCCESS == (s_ret=rtw_select_and_join_from_scanned_queue(pmlmepriv)))
++			{
++			     _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
++			}
++			else if(s_ret == 2)//there is no need to wait for join
++			{
++				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++				rtw_indicate_connect(adapter);
++			}
++			else
++			{
++				DBG_871X("try_to_join, but select scanning queue fail, to_roaming:%d\n", rtw_to_roaming(adapter));
++				#ifdef CONFIG_LAYER2_ROAMING
++				if (rtw_to_roaming(adapter) != 0) {
++					if( --pmlmepriv->to_roaming == 0
++						|| _SUCCESS != rtw_sitesurvey_cmd(adapter, &pmlmepriv->assoc_ssid, 1, NULL, 0)
++					) {
++						rtw_set_roaming(adapter, 0);
++#ifdef CONFIG_INTEL_WIDI
++						if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING)
++						{
++							_rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
++							intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL);
++							DBG_871X("change to widi listen\n");
++						}
++#endif // CONFIG_INTEL_WIDI
++						rtw_free_assoc_resources(adapter, 1);
++						rtw_indicate_disconnect(adapter);
++					} else {
++						pmlmepriv->to_join = _TRUE;
++					}
++				}
++				#endif
++				_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++			}
++		}
++	}
++
++	indicate_wx_scan_complete_event(adapter);
++	//DBG_871X("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time));
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++#ifdef CONFIG_P2P_PS
++	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
++		p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
++	}
++#endif // CONFIG_P2P_PS
++
++	rtw_os_xmit_schedule(adapter);
++#ifdef CONFIG_CONCURRENT_MODE
++	rtw_os_xmit_schedule(adapter->pbuddy_adapter);
++#endif
++#ifdef CONFIG_DUALMAC_CONCURRENT
++	dc_resume_xmit(adapter);
++#endif
++
++#ifdef CONFIG_DRVEXT_MODULE_WSC
++	drvext_surveydone_callback(&adapter->drvextpriv);
++#endif
++
++#ifdef DBG_CONFIG_ERROR_DETECT
++#ifdef CONFIG_INTEL_WIDI
++	if (adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_NONE)
++#endif
++	{
++		struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
++		if(pmlmeext->sitesurvey_res.bss_cnt == 0){
++			rtw_hal_sreset_reset(adapter);
++		}
++	}
++#endif
++
++#ifdef CONFIG_IOCTL_CFG80211
++	rtw_cfg80211_surveydone_event_callback(adapter);
++#endif //CONFIG_IOCTL_CFG80211
++
++_func_exit_;
++
++}
++
++void rtw_dummy_event_callback(_adapter *adapter , u8 *pbuf)
++{
++
++}
++
++void rtw_fwdbg_event_callback(_adapter *adapter , u8 *pbuf)
++{
++
++}
++
++static void free_scanqueue(struct	mlme_priv *pmlmepriv)
++{
++	_irqL irqL, irqL0;
++	_queue *free_queue = &pmlmepriv->free_bss_pool;
++	_queue *scan_queue = &pmlmepriv->scanned_queue;
++	_list	*plist, *phead, *ptemp;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+free_scanqueue\n"));
++	_enter_critical_bh(&scan_queue->lock, &irqL0);
++	_enter_critical_bh(&free_queue->lock, &irqL);
++
++	phead = get_list_head(scan_queue);
++	plist = get_next(phead);
++
++	while (plist != phead)
++       {
++		ptemp = get_next(plist);
++		rtw_list_delete(plist);
++		rtw_list_insert_tail(plist, &free_queue->queue);
++		plist =ptemp;
++		pmlmepriv->num_of_scanned --;
++        }
++
++	_exit_critical_bh(&free_queue->lock, &irqL);
++	_exit_critical_bh(&scan_queue->lock, &irqL0);
++
++_func_exit_;
++}
++
++/*
++*rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
++*/
++void rtw_free_assoc_resources(_adapter *adapter, int lock_scanned_queue)
++{
++	_irqL irqL;
++	struct wlan_network* pwlan = NULL;
++	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
++	struct	sta_priv *pstapriv = &adapter->stapriv;
++	struct wlan_network *tgt_network = &pmlmepriv->cur_network;
++
++#ifdef CONFIG_TDLS
++	struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
++#endif //CONFIG_TDLS
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+rtw_free_assoc_resources\n"));
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("tgt_network->network.MacAddress="MAC_FMT" ssid=%s\n",
++		MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid));
++
++	if(check_fwstate( pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE))
++	{
++		struct sta_info* psta;
++
++		psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
++
++#ifdef CONFIG_TDLS
++		if(ptdlsinfo->setup_state != TDLS_STATE_NONE)
++		{
++			rtw_tdls_cmd(adapter, myid(&(adapter->eeprompriv)), TDLS_RS_RCR);
++			rtw_reset_tdls_info(adapter);
++			rtw_free_all_stainfo(adapter);
++			_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++		}
++		else
++#endif //CONFIG_TDLS
++		{
++			_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++			rtw_free_stainfo(adapter,  psta);
++		}
++
++		_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++	}
++
++	if(check_fwstate( pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE))
++	{
++		struct sta_info* psta;
++
++		rtw_free_all_stainfo(adapter);
++
++		psta = rtw_get_bcmc_stainfo(adapter);
++		_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++		rtw_free_stainfo(adapter, psta);
++		_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++		rtw_init_bcmc_stainfo(adapter);
++	}
++
++	if(lock_scanned_queue)
++		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++	pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
++	if(pwlan)
++	{
++		pwlan->fixed = _FALSE;
++#ifdef CONFIG_P2P
++		if(!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE))
++		{
++			u32 p2p_ielen=0;
++			u8  *p2p_ie;
++			//u16 capability;
++			u8 *pcap = NULL;
++			u32 capability_len=0;
++
++			//DBG_871X("free disconnecting network\n");
++			//rtw_free_network_nolock(pmlmepriv, pwlan);
++
++			if((p2p_ie=rtw_get_p2p_ie(pwlan->network.IEs+_FIXED_IE_LENGTH_, pwlan->network.IELength-_FIXED_IE_LENGTH_, NULL, &p2p_ielen)))
++			{
++				pcap = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, NULL, &capability_len);
++				if(pcap && capability_len==2)
++				{
++					u16 cap = *(u16*)pcap ;
++					*(u16*)pcap = cap&0x00ff;//clear group capability when free this network
++				}
++			}
++
++			rtw_set_scan_deny(adapter, 2000);
++			//rtw_clear_scan_deny(adapter);
++		}
++#endif //CONFIG_P2P
++	}
++	else
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_free_assoc_resources : pwlan== NULL \n\n"));
++	}
++
++
++	if((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count== 1))
++		/*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/)
++	{
++		rtw_free_network_nolock(pmlmepriv, pwlan);
++	}
++
++	if(lock_scanned_queue)
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++	adapter->securitypriv.key_mask = 0;
++
++_func_exit_;
++
++}
++
++/*
++*rtw_indicate_connect: the caller has to lock pmlmepriv->lock
++*/
++void rtw_indicate_connect(_adapter *padapter)
++{
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_connect\n"));
++
++	pmlmepriv->to_join = _FALSE;
++
++	if(!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
++	{
++
++#ifdef CONFIG_SW_ANTENNA_DIVERSITY
++	rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_LINK, 0);
++#endif
++	set_fwstate(pmlmepriv, _FW_LINKED);
++
++	rtw_led_control(padapter, LED_CTL_LINK);
++
++#ifdef CONFIG_DRVEXT_MODULE
++	if(padapter->drvextpriv.enable_wpa)
++	{
++		indicate_l2_connect(padapter);
++	}
++	else
++#endif
++	{
++		rtw_os_indicate_connect(padapter);
++	}
++
++	}
++
++	rtw_set_roaming(padapter, 0);
++
++#ifdef CONFIG_INTEL_WIDI
++	if(padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING)
++	{
++		_rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
++		intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_WK, NULL);
++		DBG_871X("change to widi listen\n");
++	}
++#endif // CONFIG_INTEL_WIDI
++
++	rtw_set_scan_deny(padapter, 3000);
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("-rtw_indicate_connect: fw_state=0x%08x\n", get_fwstate(pmlmepriv)));
++
++_func_exit_;
++
++}
++
++
++/*
++*rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
++*/
++void rtw_indicate_disconnect( _adapter *padapter )
++{
++	struct	mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("+rtw_indicate_disconnect\n"));
++
++	_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
++
++	if(rtw_to_roaming(padapter) > 0)
++		_clr_fwstate_(pmlmepriv, _FW_LINKED);
++
++	if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)
++		|| (rtw_to_roaming(padapter) <= 0)
++	)
++	{
++		rtw_os_indicate_disconnect(padapter);
++
++		//set ips_deny_time to avoid enter IPS before LPS leave
++		padapter->pwrctrlpriv.ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(3000);
++
++	      _clr_fwstate_(pmlmepriv, _FW_LINKED);
++
++		rtw_led_control(padapter, LED_CTL_NO_LINK);
++
++		rtw_clear_scan_deny(padapter);
++
++	}
++
++#ifdef CONFIG_P2P_PS
++	p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
++#endif // CONFIG_P2P_PS
++
++#ifdef CONFIG_LPS
++#ifdef CONFIG_WOWLAN
++	if(padapter->pwrctrlpriv.wowlan_mode==_FALSE)
++#endif //CONFIG_WOWLAN
++	rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
++
++#endif
++
++_func_exit_;
++}
++
++inline void rtw_indicate_scan_done( _adapter *padapter, bool aborted)
++{
++	rtw_os_indicate_scan_done(padapter, aborted);
++}
++
++void rtw_scan_abort(_adapter *adapter)
++{
++	u32 cnt=0;
++	u32 start;
++	struct mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext = &(adapter->mlmeextpriv);
++
++	start = rtw_get_current_time();
++	pmlmeext->scan_abort = _TRUE;
++	while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)
++		&& rtw_get_passing_time_ms(start) <= 200) {
++
++		if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
++			break;
++
++		DBG_871X(FUNC_NDEV_FMT"fw_state=_FW_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
++		rtw_msleep_os(20);
++	}
++
++	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
++		if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
++			DBG_871X(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
++		#ifdef CONFIG_PLATFORM_MSTAR
++		//_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
++		set_survey_timer(pmlmeext, 0);
++		_set_timer(&pmlmepriv->scan_to_timer, 50);
++		#endif
++		rtw_indicate_scan_done(adapter, _TRUE);
++	}
++	pmlmeext->scan_abort = _FALSE;
++}
++
++static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork)
++{
++	int i;
++	struct sta_info *bmc_sta, *psta=NULL;
++	struct recv_reorder_ctrl *preorder_ctrl;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++
++	psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
++	if(psta==NULL) {
++		psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
++	}
++
++	if(psta) //update ptarget_sta
++	{
++		DBG_871X("%s\n", __FUNCTION__);
++
++		psta->aid  = pnetwork->join_res;
++#ifdef CONFIG_CONCURRENT_MODE
++
++		if(PRIMARY_ADAPTER == padapter->adapter_type)
++			psta->mac_id=0;
++		else
++			psta->mac_id=2;
++#else
++		psta->mac_id=0;
++#endif
++
++		psta->raid = networktype_to_raid(pmlmeext->cur_wireless_mode);
++
++		//security related
++		if(padapter->securitypriv.dot11AuthAlgrthm== dot11AuthAlgrthm_8021X)
++		{
++			padapter->securitypriv.binstallGrpkey=_FALSE;
++			padapter->securitypriv.busetkipkey=_FALSE;
++			padapter->securitypriv.bgrpkey_handshake=_FALSE;
++
++			psta->ieee8021x_blocked=_TRUE;
++			psta->dot118021XPrivacy=padapter->securitypriv.dot11PrivacyAlgrthm;
++
++			_rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof (union Keytype));
++
++			_rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype));
++			_rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype));
++
++			_rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48));
++#ifdef CONFIG_IEEE80211W
++			_rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof (union pn48));
++#endif //CONFIG_IEEE80211W
++			_rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48));
++		}
++
++		//	Commented by Albert 2012/07/21
++		//	When doing the WPS, the wps_ie_len won't equal to 0
++		//	And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted.
++		if ( padapter->securitypriv.wps_ie_len != 0 )
++		{
++			psta->ieee8021x_blocked=_TRUE;
++			padapter->securitypriv.wps_ie_len = 0;
++		}
++
++
++		//for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
++		//if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff
++		//todo: check if AP can send A-MPDU packets
++		for(i=0; i < 16 ; i++)
++		{
++			//preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
++			preorder_ctrl = &psta->recvreorder_ctrl[i];
++			preorder_ctrl->enable = _FALSE;
++			preorder_ctrl->indicate_seq = 0xffff;
++			#ifdef DBG_RX_SEQ
++			DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
++				preorder_ctrl->indicate_seq);
++			#endif
++			preorder_ctrl->wend_b= 0xffff;
++			preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
++		}
++
++
++		bmc_sta = rtw_get_bcmc_stainfo(padapter);
++		if(bmc_sta)
++		{
++			for(i=0; i < 16 ; i++)
++			{
++				//preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
++				preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
++				preorder_ctrl->enable = _FALSE;
++				preorder_ctrl->indicate_seq = 0xffff;
++				#ifdef DBG_RX_SEQ
++				DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
++					preorder_ctrl->indicate_seq);
++				#endif
++				preorder_ctrl->wend_b= 0xffff;
++				preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
++			}
++		}
++
++
++		//misc.
++		update_sta_info(padapter, psta);
++
++	}
++
++	return psta;
++
++}
++
++//pnetwork : returns from rtw_joinbss_event_callback
++//ptarget_wlan: found from scanned_queue
++static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network  *pnetwork)
++{
++	struct mlme_priv	*pmlmepriv = &(padapter->mlmepriv);
++	struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\nfw_state:%x, BSSID:"MAC_FMT"\n"
++		,get_fwstate(pmlmepriv), MAC_ARG(pnetwork->network.MacAddress)));
++
++
++	// why not use ptarget_wlan??
++	_rtw_memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
++
++	cur_network->aid = pnetwork->join_res;
++
++
++#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
++	rtw_set_signal_stat_timer(&padapter->recvpriv);
++#endif
++	padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
++	padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
++	//the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled)
++	padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
++	#if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
++		DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
++			"\n"
++			, FUNC_ADPT_ARG(padapter)
++			, padapter->recvpriv.signal_strength
++			, padapter->recvpriv.rssi
++			, padapter->recvpriv.signal_qual
++	);
++	#endif
++#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
++	rtw_set_signal_stat_timer(&padapter->recvpriv);
++#endif
++
++	//update fw_state //will clr _FW_UNDER_LINKING here indirectly
++	switch(pnetwork->network.InfrastructureMode)
++	{
++		case Ndis802_11Infrastructure:
++
++				if(pmlmepriv->fw_state&WIFI_UNDER_WPS)
++					pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
++				else
++					pmlmepriv->fw_state = WIFI_STATION_STATE;
++
++				break;
++		case Ndis802_11IBSS:
++				pmlmepriv->fw_state = WIFI_ADHOC_STATE;
++				break;
++		default:
++				pmlmepriv->fw_state = WIFI_NULL_STATE;
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Invalid network_mode\n"));
++				break;
++	}
++
++	rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof (NDIS_802_11_FIXED_IEs),
++									(cur_network->network.IELength));
++
++#ifdef CONFIG_80211N_HT
++	rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength, (u8) cur_network->network.Configuration.DSConfig);
++#endif
++
++
++}
++
++//Notes: the fucntion could be > passive_level (the same context as Rx tasklet)
++//pnetwork : returns from rtw_joinbss_event_callback
++//ptarget_wlan: found from scanned_queue
++//if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if  "ptarget_sta" & "ptarget_wlan" exist.
++//if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist.
++//if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL).
++//
++//#define REJOIN
++void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf)
++{
++	_irqL irqL,irqL2;
++	static u8 retry=0;
++	u8 timer_cancelled;
++	struct sta_info *ptarget_sta= NULL, *pcur_sta = NULL;
++	struct	sta_priv *pstapriv = &adapter->stapriv;
++	struct	mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++	struct wlan_network 	*pnetwork	= (struct wlan_network *)pbuf;
++	struct wlan_network 	*cur_network = &(pmlmepriv->cur_network);
++	struct wlan_network	*pcur_wlan = NULL, *ptarget_wlan = NULL;
++	unsigned int 		the_same_macaddr = _FALSE;
++
++_func_enter_;
++
++#ifdef CONFIG_RTL8712
++       //endian_convert
++	pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
++	pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
++	pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
++	pnetwork->network.Ssid.SsidLength = le32_to_cpu(pnetwork->network.Ssid.SsidLength);
++	pnetwork->network.Privacy =le32_to_cpu( pnetwork->network.Privacy);
++	pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
++	pnetwork->network.NetworkTypeInUse =le32_to_cpu(pnetwork->network.NetworkTypeInUse) ;
++	pnetwork->network.Configuration.ATIMWindow = le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
++	pnetwork->network.Configuration.BeaconPeriod = le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
++	pnetwork->network.Configuration.DSConfig = le32_to_cpu(pnetwork->network.Configuration.DSConfig);
++	pnetwork->network.Configuration.FHConfig.DwellTime=le32_to_cpu(pnetwork->network.Configuration.FHConfig.DwellTime);
++	pnetwork->network.Configuration.FHConfig.HopPattern=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopPattern);
++	pnetwork->network.Configuration.FHConfig.HopSet=le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
++	pnetwork->network.Configuration.FHConfig.Length=le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
++	pnetwork->network.Configuration.Length = le32_to_cpu(pnetwork->network.Configuration.Length);
++	pnetwork->network.InfrastructureMode = le32_to_cpu(pnetwork->network.InfrastructureMode);
++	pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength );
++#endif
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("joinbss event call back received with res=%d\n", pnetwork->join_res));
++
++	rtw_get_encrypt_decrypt_from_registrypriv(adapter);
++
++
++	if (pmlmepriv->assoc_ssid.SsidLength == 0)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@   joinbss event call back  for Any SSid\n"));
++	}
++	else
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("@@@@@   rtw_joinbss_event_callback for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid));
++	}
++
++	the_same_macaddr = _rtw_memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
++
++	pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network);
++	if(pnetwork->network.Length > sizeof(WLAN_BSSID_EX))
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n\n ***joinbss_evt_callback return a wrong bss ***\n\n"));
++		goto ignore_joinbss_callback;
++	}
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("\n rtw_joinbss_event_callback !! _enter_critical \n"));
++
++	if(pnetwork->join_res > 0)
++	{
++		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		retry = 0;
++		if (check_fwstate(pmlmepriv,_FW_UNDER_LINKING) )
++		{
++			//s1. find ptarget_wlan
++			if(check_fwstate(pmlmepriv, _FW_LINKED) )
++			{
++				if(the_same_macaddr == _TRUE)
++				{
++					ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
++				}
++				else
++				{
++					pcur_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
++					if(pcur_wlan)	pcur_wlan->fixed = _FALSE;
++
++					pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
++					if(pcur_sta){
++						_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
++						rtw_free_stainfo(adapter,  pcur_sta);
++						_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2);
++					}
++
++					ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
++					if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){
++						if(ptarget_wlan)	ptarget_wlan->fixed = _TRUE;
++					}
++				}
++
++			}
++			else
++			{
++				ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
++				if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE){
++					if(ptarget_wlan)	ptarget_wlan->fixed = _TRUE;
++				}
++			}
++
++			//s2. update cur_network
++			if(ptarget_wlan)
++			{
++				rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
++			}
++			else
++			{
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't find ptarget_wlan when joinbss_event callback\n"));
++				_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++				goto ignore_joinbss_callback;
++			}
++
++
++			//s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode
++			if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
++			{
++				ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
++				if(ptarget_sta==NULL)
++				{
++					RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't update stainfo when joinbss_event callback\n"));
++					_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++					goto ignore_joinbss_callback;
++				}
++			}
++
++			//s4. indicate connect
++			if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
++			{
++				rtw_indicate_connect(adapter);
++			}
++			else
++			{
++				//adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
++			}
++
++
++			//s5. Cancle assoc_timer
++			_cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled);
++
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("Cancle assoc_timer\n"));
++
++		}
++		else
++		{
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_joinbss_event_callback err: fw_state:%x", get_fwstate(pmlmepriv)));
++			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			goto ignore_joinbss_callback;
++		}
++
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++	}
++	else if(pnetwork->join_res == -4)
++	{
++		rtw_reset_securitypriv(adapter);
++		_set_timer(&pmlmepriv->assoc_timer, 1);
++
++		//rtw_free_assoc_resources(adapter, 1);
++
++		if((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == _TRUE)
++		{
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n", get_fwstate(pmlmepriv)));
++			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++		}
++
++	}
++	else //if join_res < 0 (join fails), then try again
++	{
++
++		#ifdef REJOIN
++		res = _FAIL;
++		if(retry < 2) {
++			res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_select_and_join_from_scanned_queue again! res:%d\n",res));
++		}
++
++		 if(res == _SUCCESS)
++		{
++			//extend time of assoc_timer
++			_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
++			retry++;
++		}
++		else if(res == 2)//there is no need to wait for join
++		{
++			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++			rtw_indicate_connect(adapter);
++		}
++		else
++		{
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Set Assoc_Timer = 1; can't find match ssid in scanned_q \n"));
++		#endif
++
++			_set_timer(&pmlmepriv->assoc_timer, 1);
++			//rtw_free_assoc_resources(adapter, 1);
++			_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
++
++		#ifdef REJOIN
++			retry = 0;
++		}
++		#endif
++	}
++
++ignore_joinbss_callback:
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++	_func_exit_;
++}
++
++void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf)
++{
++	struct wlan_network 	*pnetwork	= (struct wlan_network *)pbuf;
++
++_func_enter_;
++
++	mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
++
++	rtw_os_xmit_schedule(adapter);
++
++#ifdef CONFIG_CONCURRENT_MODE
++	rtw_os_xmit_schedule(adapter->pbuddy_adapter);
++#endif
++
++#ifdef CONFIG_DUALMAC_CONCURRENT
++	dc_resume_xmit(adapter);
++#endif
++
++_func_exit_;
++}
++
++void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf)
++{
++	_irqL irqL;
++	struct sta_info *psta;
++	struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
++	struct stassoc_event	*pstassoc	= (struct stassoc_event*)pbuf;
++	struct wlan_network 	*cur_network = &(pmlmepriv->cur_network);
++	struct wlan_network	*ptarget_wlan = NULL;
++
++_func_enter_;
++
++	if(rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE)
++		return;
++
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
++	{
++		psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
++		if(psta)
++		{
++#ifdef CONFIG_IOCTL_CFG80211
++#ifdef COMPAT_KERNEL_RELEASE
++
++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++			u8 *passoc_req = NULL;
++			u32 assoc_req_len;
++
++			_enter_critical_bh(&psta->lock, &irqL);
++			if(psta->passoc_req && psta->assoc_req_len>0)
++			{
++				passoc_req = rtw_zmalloc(psta->assoc_req_len);
++				if(passoc_req)
++				{
++					assoc_req_len = psta->assoc_req_len;
++					_rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len);
++
++					rtw_mfree(psta->passoc_req , psta->assoc_req_len);
++					psta->passoc_req = NULL;
++					psta->assoc_req_len = 0;
++				}
++			}
++			_exit_critical_bh(&psta->lock, &irqL);
++
++			if(passoc_req && assoc_req_len>0)
++			{
++				rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
++
++				rtw_mfree(passoc_req, assoc_req_len);
++			}
++#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++#endif //CONFIG_IOCTL_CFG80211
++
++			//bss_cap_update_on_sta_join(adapter, psta);
++			//sta_info_update(adapter, psta);
++			ap_sta_info_defer_update(adapter, psta);
++		}
++
++		goto exit;
++	}
++#endif
++
++	psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
++	if( psta != NULL)
++	{
++		//the sta have been in sta_info_queue => do nothing
++
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Error: rtw_stassoc_event_callback: sta has been in sta_hash_queue \n"));
++
++		goto exit; //(between drv has received this event before and  fw have not yet to set key to CAM_ENTRY)
++	}
++
++	psta = rtw_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
++	if (psta == NULL) {
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Can't alloc sta_info when rtw_stassoc_event_callback\n"));
++		goto exit;
++	}
++
++	//to do : init sta_info variable
++	psta->qos_option = 0;
++	psta->mac_id = (uint)pstassoc->cam_id;
++	//psta->aid = (uint)pstassoc->cam_id;
++
++	if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
++		psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
++
++	psta->ieee8021x_blocked = _FALSE;
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	if ( (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE ) ||
++		(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)==_TRUE ) )
++	{
++		if(adapter->stapriv.asoc_sta_count== 2)
++		{
++			_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
++			if(ptarget_wlan)	ptarget_wlan->fixed = _TRUE;
++			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			// a sta + bc/mc_stainfo (not Ibss_stainfo)
++			rtw_indicate_connect(adapter);
++		}
++	}
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++
++	mlmeext_sta_add_event_callback(adapter, psta);
++
++#ifdef CONFIG_RTL8711
++	//submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta
++	rtw_setstakey_cmd(adapter, (unsigned char*)psta, _FALSE);
++#endif
++
++exit:
++
++_func_exit_;
++
++}
++
++void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf)
++{
++	_irqL irqL,irqL2;
++	struct sta_info *psta;
++	struct wlan_network* pwlan = NULL;
++	WLAN_BSSID_EX    *pdev_network=NULL;
++	u8* pibss = NULL;
++	struct	mlme_priv	*pmlmepriv = &(adapter->mlmepriv);
++	struct 	stadel_event *pstadel	= (struct stadel_event*)pbuf;
++	struct	sta_priv *pstapriv = &adapter->stapriv;
++	struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
++
++_func_enter_;
++
++        if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
++        {
++#ifdef CONFIG_IOCTL_CFG80211
++#ifdef COMPAT_KERNEL_RELEASE
++
++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++		rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16*)pstadel->rsvd);
++#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++#endif //CONFIG_IOCTL_CFG80211
++
++		return;
++        }
++
++
++	mlmeext_sta_del_event_callback(adapter);
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL2);
++
++	if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
++	{
++		#ifdef CONFIG_LAYER2_ROAMING
++		if (rtw_to_roaming(adapter) > 0)
++			pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */
++		else if (rtw_to_roaming(adapter) == 0)
++			rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
++#ifdef CONFIG_INTEL_WIDI
++		if(adapter->mlmepriv.widi_state != INTEL_WIDI_STATE_CONNECTED)
++#endif // CONFIG_INTEL_WIDI
++		if(*((unsigned short *)(pstadel->rsvd)) != WLAN_REASON_EXPIRATION_CHK)
++			rtw_set_roaming(adapter, 0); /* don't roam */
++		#endif
++
++		rtw_free_uc_swdec_pending_queue(adapter);
++
++		rtw_free_assoc_resources(adapter, 1);
++		rtw_indicate_disconnect(adapter);
++		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++		// remove the network entry in scanned_queue
++		pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
++		if (pwlan) {
++			pwlan->fixed = _FALSE;
++			rtw_free_network_nolock(pmlmepriv, pwlan);
++		}
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++		_rtw_roaming(adapter, tgt_network);
++
++#ifdef CONFIG_INTEL_WIDI
++		if (!rtw_to_roaming(adapter))
++			process_intel_widi_disconnect(adapter, 1);
++#endif // CONFIG_INTEL_WIDI
++	}
++
++	if ( check_fwstate(pmlmepriv,WIFI_ADHOC_MASTER_STATE) ||
++	      check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
++	{
++		psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
++
++		_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++		rtw_free_stainfo(adapter,  psta);
++		_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++		if(adapter->stapriv.asoc_sta_count== 1) //a sta + bc/mc_stainfo (not Ibss_stainfo)
++		{
++			//rtw_indicate_disconnect(adapter);//removed at 20091105
++			_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			//free old ibss network
++			//pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr);
++			pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
++			if(pwlan)
++			{
++				pwlan->fixed = _FALSE;
++				rtw_free_network_nolock(pmlmepriv, pwlan);
++			}
++			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			//re-create ibss
++			pdev_network = &(adapter->registrypriv.dev_network);
++			pibss = adapter->registrypriv.dev_network.MacAddress;
++
++			_rtw_memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network));
++
++			_rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
++			_rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
++
++			rtw_update_registrypriv_dev_network(adapter);
++
++			rtw_generate_random_ibss(pibss);
++
++			if(check_fwstate(pmlmepriv,WIFI_ADHOC_STATE))
++			{
++				set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
++				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
++			}
++
++			if(rtw_createbss_cmd(adapter)!=_SUCCESS)
++			{
++
++				RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("***Error=>stadel_event_callback: rtw_createbss_cmd status FAIL*** \n "));
++
++			}
++
++
++		}
++
++	}
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL2);
++
++_func_exit_;
++
++}
++
++
++void rtw_cpwm_event_callback(PADAPTER padapter, u8 *pbuf)
++{
++#ifdef CONFIG_LPS_LCLK
++	struct reportpwrstate_parm *preportpwrstate;
++#endif
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("rtw_cpwm_event_callback !!!\n"));
++#ifdef CONFIG_LPS_LCLK
++	preportpwrstate = (struct reportpwrstate_parm*)pbuf;
++	preportpwrstate->state |= (u8)(padapter->pwrctrlpriv.cpwm_tog + 0x80);
++	cpwm_int_hdl(padapter, preportpwrstate);
++#endif
++
++_func_exit_;
++
++}
++
++/*
++* _rtw_join_timeout_handler - Timeout/faliure handler for CMD JoinBss
++* @adapter: pointer to _adapter structure
++*/
++void _rtw_join_timeout_handler (_adapter *adapter)
++{
++	_irqL irqL;
++	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
++#ifdef CONFIG_LAYER2_ROAMING
++	int do_join_r;
++#endif //CONFIG_LAYER2_ROAMING
++
++#if 0
++	if (adapter->bDriverStopped == _TRUE){
++		_rtw_up_sema(&pmlmepriv->assoc_terminate);
++		return;
++	}
++#endif
++
++_func_enter_;
++#ifdef PLATFORM_FREEBSD
++		rtw_mtx_lock(NULL);
++		 if (callout_pending(&adapter->mlmepriv.assoc_timer.callout)) {
++			 /* callout was reset */
++			 //mtx_unlock(&sc->sc_mtx);
++			 rtw_mtx_unlock(NULL);
++			 return;
++		 }
++		 if (!callout_active(&adapter->mlmepriv.assoc_timer.callout)) {
++			 /* callout was stopped */
++			 //mtx_unlock(&sc->sc_mtx);
++			 rtw_mtx_unlock(NULL);
++			 return;
++		 }
++		 callout_deactivate(&adapter->mlmepriv.assoc_timer.callout);
++
++
++#endif
++
++	DBG_871X("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
++
++	if(adapter->bDriverStopped ||adapter->bSurpriseRemoved)
++		return;
++
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	#ifdef CONFIG_LAYER2_ROAMING
++	if (rtw_to_roaming(adapter) > 0) { /* join timeout caused by roaming */
++		while(1) {
++			pmlmepriv->to_roaming--;
++			if (rtw_to_roaming(adapter) != 0) { /* try another */
++				DBG_871X("%s try another roaming\n", __FUNCTION__);
++				if( _SUCCESS!=(do_join_r=rtw_do_join(adapter)) ) {
++					DBG_871X("%s roaming do_join return %d\n", __FUNCTION__ ,do_join_r);
++					continue;
++				}
++				break;
++			} else {
++#ifdef CONFIG_INTEL_WIDI
++				if(adapter->mlmepriv.widi_state == INTEL_WIDI_STATE_ROAMING)
++				{
++					_rtw_memset(pmlmepriv->sa_ext, 0x00, L2SDTA_SERVICE_VE_LEN);
++					intel_widi_wk_cmd(adapter, INTEL_WIDI_LISTEN_WK, NULL);
++					DBG_871X("change to widi listen\n");
++				}
++#endif // CONFIG_INTEL_WIDI
++				DBG_871X("%s We've try roaming but fail\n", __FUNCTION__);
++				rtw_indicate_disconnect(adapter);
++				break;
++			}
++		}
++
++	} else
++	#endif
++	{
++		rtw_indicate_disconnect(adapter);
++		free_scanqueue(pmlmepriv);//???
++
++#ifdef CONFIG_IOCTL_CFG80211
++		//indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED
++		rtw_cfg80211_indicate_disconnect(adapter);
++#endif //CONFIG_IOCTL_CFG80211
++
++	}
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++
++#ifdef CONFIG_DRVEXT_MODULE_WSC
++	drvext_assoc_fail_indicate(&adapter->drvextpriv);
++#endif
++#ifdef PLATFORM_FREEBSD
++		rtw_mtx_unlock(NULL);
++#endif
++
++_func_exit_;
++
++}
++
++/*
++* rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
++* @adapter: pointer to _adapter structure
++*/
++void rtw_scan_timeout_handler (_adapter *adapter)
++{
++	_irqL irqL;
++	struct	mlme_priv *pmlmepriv = &adapter->mlmepriv;
++
++	DBG_871X(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++
++	_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
++
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++
++	rtw_indicate_scan_done(adapter, _TRUE);
++
++}
++
++static void rtw_auto_scan_handler(_adapter *padapter)
++{
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
++
++	//auto site survey per 60sec
++	if(pmlmepriv->scan_interval >0)
++	{
++		pmlmepriv->scan_interval--;
++		if(pmlmepriv->scan_interval==0)
++		{
++/*
++			if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
++			{
++				DBG_871X("exit %s when _FW_UNDER_SURVEY|_FW_UNDER_LINKING -> \n", __FUNCTION__);
++				return;
++			}
++
++			if(pmlmepriv->sitesurveyctrl.traffic_busy == _TRUE)
++			{
++				DBG_871X("%s exit cause traffic_busy(%x)\n",__FUNCTION__, pmlmepriv->sitesurveyctrl.traffic_busy);
++				return;
++			}
++*/
++
++#ifdef CONFIG_CONCURRENT_MODE
++			if (rtw_buddy_adapter_up(padapter))
++			{
++				if ((check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE) ||
++					(padapter->pbuddy_adapter->mlmepriv.LinkDetectInfo.bBusyTraffic == _TRUE))
++				{
++					DBG_871X("%s, but buddy_intf is under scanning or linking or BusyTraffic\n", __FUNCTION__);
++					return;
++				}
++			}
++#endif
++
++			DBG_871X("%s\n", __FUNCTION__);
++
++			rtw_set_802_11_bssid_list_scan(padapter, NULL, 0);
++
++			pmlmepriv->scan_interval = SCAN_INTERVAL;// 30*2 sec = 60sec
++
++		}
++
++	}
++
++}
++
++void rtw_dynamic_check_timer_handlder(_adapter *adapter)
++{
++#ifdef CONFIG_AP_MODE
++	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
++#endif //CONFIG_AP_MODE
++	struct registry_priv *pregistrypriv = &adapter->registrypriv;
++#ifdef CONFIG_CONCURRENT_MODE
++	PADAPTER pbuddy_adapter = adapter->pbuddy_adapter;
++#endif
++
++	if(!adapter)
++		return;
++
++	if(adapter->hw_init_completed == _FALSE)
++		return;
++
++	if ((adapter->bDriverStopped == _TRUE)||(adapter->bSurpriseRemoved== _TRUE))
++		return;
++
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if(pbuddy_adapter)
++	{
++		if(adapter->net_closed == _TRUE && pbuddy_adapter->net_closed == _TRUE)
++		{
++			return;
++		}
++	}
++	else
++#endif //CONFIG_CONCURRENT_MODE
++	if(adapter->net_closed == _TRUE)
++	{
++		return;
++	}
++
++	rtw_dynamic_chk_wk_cmd(adapter);
++
++	if(pregistrypriv->wifi_spec==1)
++	{
++#ifdef CONFIG_P2P
++		struct wifidirect_info *pwdinfo = &adapter->wdinfo;
++		if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
++#endif
++		{
++			//auto site survey
++			rtw_auto_scan_handler(adapter);
++		}
++	}
++
++#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++#ifdef CONFIG_AP_MODE
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++	{
++		expire_timeout_chk(adapter);
++	}
++#endif
++#endif //!CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++
++#ifdef CONFIG_BR_EXT
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
++	rcu_read_lock();
++#endif	// (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
++
++#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
++	if( adapter->pnetdev->br_port
++#else	// (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
++	if( rcu_dereference(adapter->pnetdev->rx_handler_data)
++#endif	// (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
++		&& (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) )
++	{
++		// expire NAT2.5 entry
++		void nat25_db_expire(_adapter *priv);
++		nat25_db_expire(adapter);
++
++		if (adapter->pppoe_connection_in_progress > 0) {
++			adapter->pppoe_connection_in_progress--;
++		}
++
++		// due to rtw_dynamic_check_timer_handlder() is called every 2 seconds
++		if (adapter->pppoe_connection_in_progress > 0) {
++			adapter->pppoe_connection_in_progress--;
++		}
++	}
++
++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
++	rcu_read_unlock();
++#endif	// (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
++
++#endif	// CONFIG_BR_EXT
++
++}
++
++
++#ifdef CONFIG_SET_SCAN_DENY_TIMER
++inline bool rtw_is_scan_deny(_adapter *adapter)
++{
++	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
++	return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
++}
++
++inline void rtw_clear_scan_deny(_adapter *adapter)
++{
++	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
++	ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
++	if (0)
++	DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
++}
++
++void rtw_set_scan_deny_timer_hdl(_adapter *adapter)
++{
++	rtw_clear_scan_deny(adapter);
++}
++
++void rtw_set_scan_deny(_adapter *adapter, u32 ms)
++{
++	struct mlme_priv *mlmepriv = &adapter->mlmepriv;
++#ifdef CONFIG_CONCURRENT_MODE
++	struct mlme_priv *b_mlmepriv;
++#endif
++
++	if (0)
++	DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
++	ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
++	_set_timer(&mlmepriv->set_scan_deny_timer, ms);
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if (!adapter->pbuddy_adapter)
++		return;
++
++	if (0)
++	DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter->pbuddy_adapter));
++	b_mlmepriv = &adapter->pbuddy_adapter->mlmepriv;
++	ATOMIC_SET(&b_mlmepriv->set_scan_deny, 1);
++	_set_timer(&b_mlmepriv->set_scan_deny_timer, ms);
++#endif
++
++}
++#endif
++
++#if defined(IEEE80211_SCAN_RESULT_EXPIRE)
++#define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 //3000 -1000
++#else
++#define RTW_SCAN_RESULT_EXPIRE 2000
++#endif
++
++#ifndef PLATFORM_FREEBSD
++/*
++* Select a new join candidate from the original @param candidate and @param competitor
++* @return _TRUE: candidate is updated
++* @return _FALSE: candidate is not updated
++*/
++static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
++	, struct wlan_network **candidate, struct wlan_network *competitor)
++{
++	int updated = _FALSE;
++	_adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
++
++
++	//check bssid, if needed
++	if(pmlmepriv->assoc_by_bssid==_TRUE) {
++		if(_rtw_memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN) ==_FALSE)
++			goto exit;
++	}
++
++	//check ssid, if needed
++	if(pmlmepriv->assoc_ssid.Ssid && pmlmepriv->assoc_ssid.SsidLength) {
++		if(	competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength
++			|| _rtw_memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength) == _FALSE
++		)
++			goto exit;
++	}
++
++	if(rtw_is_desired_network(adapter, competitor)  == _FALSE)
++		goto exit;
++
++#ifdef  CONFIG_LAYER2_ROAMING
++	if(rtw_to_roaming(adapter) > 0) {
++		if(	rtw_get_passing_time_ms((u32)competitor->last_scanned) >= RTW_SCAN_RESULT_EXPIRE
++			|| is_same_ess(&competitor->network, &pmlmepriv->cur_network.network) == _FALSE
++		)
++			goto exit;
++	}
++#endif
++
++	if(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi )
++	{
++		*candidate = competitor;
++		updated = _TRUE;
++	}
++
++#if 0
++	if(pmlmepriv->assoc_by_bssid==_TRUE) { // associate with bssid
++		if(	(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi )
++			&& _rtw_memcmp(competitor->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN)==_TRUE
++		) {
++			*candidate = competitor;
++			updated = _TRUE;
++		}
++	} else  if (pmlmepriv->assoc_ssid.SsidLength == 0 ) { // associate with ssid, but ssidlength is 0
++		if(	(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi ) ) {
++			*candidate = competitor;
++			updated = _TRUE;
++		}
++	} else
++#ifdef  CONFIG_LAYER2_ROAMING
++	if(rtw_to_roaming(adapter)) { // roaming
++		if(	(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi )
++			&& is_same_ess(&competitor->network, &pmlmepriv->cur_network.network)
++			//&&(!is_same_network(&competitor->network, &pmlmepriv->cur_network.network))
++			&& rtw_get_passing_time_ms((u32)competitor->last_scanned) < RTW_SCAN_RESULT_EXPIRE
++			&& rtw_is_desired_network(adapter, competitor)
++		) {
++			*candidate = competitor;
++			updated = _TRUE;
++		}
++
++	} else
++#endif
++	{ // associate with ssid
++		if(	(*candidate == NULL ||(*candidate)->network.Rssi<competitor->network.Rssi )
++			&& (competitor->network.Ssid.SsidLength==pmlmepriv->assoc_ssid.SsidLength)
++			&&((_rtw_memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength)) == _TRUE)
++			&& rtw_is_desired_network(adapter, competitor)
++		) {
++			*candidate = competitor;
++			updated = _TRUE;
++		}
++	}
++#endif
++
++	if(updated){
++		DBG_871X("[by_bssid:%u][assoc_ssid:%s]"
++			#ifdef  CONFIG_LAYER2_ROAMING
++			"[to_roaming:%u] "
++			#endif
++			"new candidate: %s("MAC_FMT", ch%u) rssi:%d\n",
++			pmlmepriv->assoc_by_bssid,
++			pmlmepriv->assoc_ssid.Ssid,
++			#ifdef  CONFIG_LAYER2_ROAMING
++			rtw_to_roaming(adapter),
++			#endif
++			(*candidate)->network.Ssid.Ssid,
++			MAC_ARG((*candidate)->network.MacAddress),
++			(*candidate)->network.Configuration.DSConfig,
++			(int)(*candidate)->network.Rssi
++		);
++	}
++
++exit:
++	return updated;
++}
++
++/*
++Calling context:
++The caller of the sub-routine will be in critical section...
++
++The caller must hold the following spinlock
++
++pmlmepriv->lock
++
++
++*/
++
++int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv )
++{
++	_irqL	irqL;
++	int ret;
++	_list	*phead;
++	_adapter *adapter;
++	_queue	*queue	= &(pmlmepriv->scanned_queue);
++	struct	wlan_network	*pnetwork = NULL;
++	struct	wlan_network	*candidate = NULL;
++	u8 		bSupportAntDiv = _FALSE;
++
++_func_enter_;
++
++	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++	phead = get_list_head(queue);
++	adapter = (_adapter *)pmlmepriv->nic_hdl;
++
++	pmlmepriv->pscanned = get_next( phead );
++
++	while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
++
++		pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
++		if(pnetwork==NULL){
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("%s return _FAIL:(pnetwork==NULL)\n", __FUNCTION__));
++			ret = _FAIL;
++			goto exit;
++		}
++
++		pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
++
++		#if 0
++		DBG_871X("MacAddress:"MAC_FMT" ssid:%s\n", MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Ssid.Ssid);
++		#endif
++
++		rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
++
++	}
++
++	if(candidate == NULL) {
++		DBG_871X("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
++		ret = _FAIL;
++		goto exit;
++	} else {
++		DBG_871X("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
++			candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
++			candidate->network.Configuration.DSConfig);
++	}
++
++
++	// check for situation of  _FW_LINKED
++	if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++	{
++		DBG_871X("%s: _FW_LINKED while ask_for_joinbss!!!\n", __FUNCTION__);
++
++		#if 0 // for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP...
++		if(is_same_network(&pmlmepriv->cur_network.network, &candidate->network))
++		{
++			DBG_871X("%s: _FW_LINKED and is same network, it needn't join again\n", __FUNCTION__);
++
++			rtw_indicate_connect(adapter);//rtw_indicate_connect again
++
++			ret = 2;
++			goto exit;
++		}
++		else
++		#endif
++		{
++			rtw_disassoc_cmd(adapter, 0, _TRUE);
++			rtw_indicate_disconnect(adapter);
++			rtw_free_assoc_resources(adapter, 0);
++		}
++	}
++
++	#ifdef CONFIG_ANTENNA_DIVERSITY
++	rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
++	if(_TRUE == bSupportAntDiv)
++	{
++		u8 CurrentAntenna;
++		rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(CurrentAntenna));
++		DBG_871X("#### Opt_Ant_(%s) , cur_Ant(%s)\n",
++			(2==candidate->network.PhyInfo.Optimum_antenna)?"A":"B",
++			(2==CurrentAntenna)?"A":"B"
++		);
++	}
++	#endif
++	set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
++	ret = rtw_joinbss_cmd(adapter, candidate);
++
++exit:
++	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++_func_exit_;
++
++	return ret;
++}
++#else
++int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv )
++{
++	_irqL	irqL;
++	_list	*phead;
++#ifdef CONFIG_ANTENNA_DIVERSITY
++	u8 CurrentAntenna;
++#endif
++	unsigned char *dst_ssid, *src_ssid;
++	_adapter *adapter;
++	_queue	*queue	= &(pmlmepriv->scanned_queue);
++	struct	wlan_network	*pnetwork = NULL;
++	struct	wlan_network	*pnetwork_max_rssi = NULL;
++	#ifdef CONFIG_LAYER2_ROAMING
++	struct wlan_network * roaming_candidate=NULL;
++	u32 cur_time=rtw_get_current_time();
++	#endif
++
++_func_enter_;
++	_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++	phead = get_list_head(queue);
++	adapter = (_adapter *)pmlmepriv->nic_hdl;
++
++	pmlmepriv->pscanned = get_next( phead );
++
++	while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
++
++		pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
++		if(pnetwork==NULL){
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("(2)rtw_select_and_join_from_scanned_queue return _FAIL:(pnetwork==NULL)\n"));
++			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			return _FAIL;
++		}
++
++		dst_ssid = pnetwork->network.Ssid.Ssid;
++		src_ssid = pmlmepriv->assoc_ssid.Ssid;
++
++		pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
++
++		#if 0
++		DBG_871X("MacAddress:"MAC_FMT" ssid:%s\n", MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Ssid.Ssid);
++		#endif
++
++		if(pmlmepriv->assoc_by_bssid==_TRUE)
++		{
++			if(_rtw_memcmp(pnetwork->network.MacAddress, pmlmepriv->assoc_bssid, ETH_ALEN)==_TRUE)
++			{
++				//remove the condition @ 20081125
++				//if((pmlmepriv->cur_network.network.InfrastructureMode==Ndis802_11AutoUnknown)||
++				//	pmlmepriv->cur_network.network.InfrastructureMode == pnetwork->network.InfrastructureMode)
++				//		goto ask_for_joinbss;
++
++				if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++				{
++					if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network))
++					{
++						//DBG_871X("select_and_join(1): _FW_LINKED and is same network, it needn't join again\n");
++
++						rtw_indicate_connect(adapter);//rtw_indicate_connect again
++						_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++						return 2;
++					}
++					else
++					{
++						rtw_disassoc_cmd(adapter, 0, _TRUE);
++						rtw_indicate_disconnect(adapter);
++						rtw_free_assoc_resources(adapter, 0);
++						_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++						goto ask_for_joinbss;
++
++					}
++				}
++				else
++				{
++					_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++					goto ask_for_joinbss;
++				}
++
++			}
++
++		} else if (pmlmepriv->assoc_ssid.SsidLength == 0) {
++			_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++			goto ask_for_joinbss;//anyway, join first selected(dequeued) pnetwork if ssid_len=0
++
++		#ifdef CONFIG_LAYER2_ROAMING
++		} else if (rtw_to_roaming(adapter) > 0) {
++
++			if(	(roaming_candidate == NULL ||roaming_candidate->network.Rssi<pnetwork->network.Rssi )
++				&& is_same_ess(&pnetwork->network, &pmlmepriv->cur_network.network)
++				//&&(!is_same_network(&pnetwork->network, &pmlmepriv->cur_network.network))
++				&&  rtw_get_time_interval_ms((u32)pnetwork->last_scanned,cur_time) < 5000
++				) {
++				roaming_candidate = pnetwork;
++				//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,
++				DBG_871X
++					("roaming_candidate???: %s("MAC_FMT")\n",
++					roaming_candidate->network.Ssid.Ssid, MAC_ARG(roaming_candidate->network.MacAddress) )
++					//)
++					;
++			}
++			continue;
++		#endif
++
++		} else if ( (pnetwork->network.Ssid.SsidLength==pmlmepriv->assoc_ssid.SsidLength)
++			&&((_rtw_memcmp(dst_ssid, src_ssid, pmlmepriv->assoc_ssid.SsidLength)) == _TRUE)
++			)
++		{
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("dst_ssid=%s, src_ssid=%s \n", dst_ssid, src_ssid));
++#ifdef CONFIG_ANTENNA_DIVERSITY
++			rtw_hal_get_def_var(adapter, HAL_DEF_CURRENT_ANTENNA, &(CurrentAntenna));
++			DBG_871X("#### dst_ssid=(%s) Opt_Ant_(%s) , cur_Ant(%s)\n", dst_ssid,
++				(2==pnetwork->network.PhyInfo.Optimum_antenna)?"A":"B",
++				(2==CurrentAntenna)?"A":"B");
++#endif
++			//remove the condition @ 20081125
++			//if((pmlmepriv->cur_network.network.InfrastructureMode==Ndis802_11AutoUnknown)||
++			//	pmlmepriv->cur_network.network.InfrastructureMode == pnetwork->network.InfrastructureMode)
++			//{
++			//	_rtw_memcpy(pmlmepriv->assoc_bssid, pnetwork->network.MacAddress, ETH_ALEN);
++			//	goto ask_for_joinbss;
++			//}
++
++			if(pmlmepriv->assoc_by_rssi==_TRUE)//if the ssid is the same, select the bss which has the max rssi
++			{
++				if( NULL==pnetwork_max_rssi|| pnetwork->network.Rssi > pnetwork_max_rssi->network.Rssi)
++						pnetwork_max_rssi = pnetwork;
++			}
++			else if(rtw_is_desired_network(adapter, pnetwork) == _TRUE)
++			{
++				if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
++				{
++#if 0
++					if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network))
++					{
++						DBG_871X("select_and_join(2): _FW_LINKED and is same network, it needn't join again\n");
++
++						rtw_indicate_connect(adapter);//rtw_indicate_connect again
++
++						return 2;
++					}
++					else
++#endif
++					{
++						rtw_disassoc_cmd(adapter, 0, _TRUE);
++						//rtw_indicate_disconnect(adapter);//
++						rtw_free_assoc_resources(adapter, 0);
++						_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++						goto ask_for_joinbss;
++					}
++				}
++				else
++				{
++					_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++					goto ask_for_joinbss;
++				}
++
++			}
++
++
++		}
++
++	}
++	_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++	#ifdef CONFIG_LAYER2_ROAMING
++	if(rtw_to_roaming(adapter) > 0 && roaming_candidate ){
++		pnetwork=roaming_candidate;
++		DBG_871X("select_and_join_from_scanned_queue: roaming_candidate: %s("MAC_FMT")\n",
++			pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress));
++		goto ask_for_joinbss;
++	}
++	#endif
++
++	if((pmlmepriv->assoc_by_rssi==_TRUE)  && (pnetwork_max_rssi!=NULL))
++	{
++		pnetwork = pnetwork_max_rssi;
++		DBG_871X("select_and_join_from_scanned_queue: pnetwork_max_rssi: %s("MAC_FMT")\n",
++			pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress));
++		goto ask_for_joinbss;
++	}
++
++	DBG_871X("(1)rtw_select_and_join_from_scanned_queue return _FAIL\n");
++
++_func_exit_;
++
++     return _FAIL;
++
++ask_for_joinbss:
++
++_func_exit_;
++
++	return rtw_joinbss_cmd(adapter, pnetwork);
++
++}
++#endif //PLATFORM_FREEBSD
++
++
++sint rtw_set_auth(_adapter * adapter,struct security_priv *psecuritypriv)
++{
++	struct	cmd_obj* pcmd;
++	struct 	setauth_parm *psetauthparm;
++	struct	cmd_priv	*pcmdpriv=&(adapter->cmdpriv);
++	sint		res=_SUCCESS;
++
++_func_enter_;
++
++	pcmd = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++	if(pcmd==NULL){
++		res= _FAIL;  //try again
++		goto exit;
++	}
++
++	psetauthparm=(struct setauth_parm*)rtw_zmalloc(sizeof(struct setauth_parm));
++	if(psetauthparm==NULL){
++		rtw_mfree((unsigned char *)pcmd, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	_rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm));
++	psetauthparm->mode=(unsigned char)psecuritypriv->dot11AuthAlgrthm;
++
++	pcmd->cmdcode = _SetAuth_CMD_;
++	pcmd->parmbuf = (unsigned char *)psetauthparm;
++	pcmd->cmdsz =  (sizeof(struct setauth_parm));
++	pcmd->rsp = NULL;
++	pcmd->rspsz = 0;
++
++
++	_rtw_init_listhead(&pcmd->list);
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("after enqueue set_auth_cmd, auth_mode=%x\n", psecuritypriv->dot11AuthAlgrthm));
++
++	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
++
++exit:
++
++_func_exit_;
++
++	return res;
++
++}
++
++
++sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx)
++{
++	u8	keylen;
++	struct cmd_obj		*pcmd;
++	struct setkey_parm	*psetkeyparm;
++	struct cmd_priv		*pcmdpriv = &(adapter->cmdpriv);
++	struct mlme_priv		*pmlmepriv = &(adapter->mlmepriv);
++	sint	res=_SUCCESS;
++
++_func_enter_;
++
++	pcmd = (struct	cmd_obj*)rtw_zmalloc(sizeof(struct	cmd_obj));
++	if(pcmd==NULL){
++		res= _FAIL;  //try again
++		goto exit;
++	}
++	psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
++	if(psetkeyparm==NULL){
++		rtw_mfree((unsigned char *)pcmd, sizeof(struct	cmd_obj));
++		res= _FAIL;
++		goto exit;
++	}
++
++	_rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
++
++	if(psecuritypriv->dot11AuthAlgrthm ==dot11AuthAlgrthm_8021X){
++		psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy;
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(unsigned char)psecuritypriv->dot118021XGrpPrivacy=%d \n", psetkeyparm->algorithm));
++	}
++	else{
++		psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm;
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=(u8)psecuritypriv->dot11PrivacyAlgrthm=%d \n", psetkeyparm->algorithm));
++
++	}
++	psetkeyparm->keyid = (u8)keyid;//0~3
++	psetkeyparm->set_tx = set_tx;
++	if (is_wep_enc(psetkeyparm->algorithm))
++		psecuritypriv->key_mask |= BIT(psetkeyparm->keyid);
++
++	DBG_871X("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid, psecuritypriv->key_mask);
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n",psetkeyparm->algorithm, keyid));
++
++	switch(psetkeyparm->algorithm){
++
++		case _WEP40_:
++			keylen=5;
++			_rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
++			break;
++		case _WEP104_:
++			keylen=13;
++			_rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
++			break;
++		case _TKIP_:
++			keylen=16;
++			_rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
++			psetkeyparm->grpkey=1;
++			break;
++		case _AES_:
++			keylen=16;
++			_rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
++			psetkeyparm->grpkey=1;
++			break;
++		default:
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",psecuritypriv->dot11PrivacyAlgrthm));
++			res= _FAIL;
++			goto exit;
++	}
++
++
++	pcmd->cmdcode = _SetKey_CMD_;
++	pcmd->parmbuf = (u8 *)psetkeyparm;
++	pcmd->cmdsz =  (sizeof(struct setkey_parm));
++	pcmd->rsp = NULL;
++	pcmd->rspsz = 0;
++
++
++	_rtw_init_listhead(&pcmd->list);
++
++	//_rtw_init_sema(&(pcmd->cmd_sem), 0);
++
++	res = rtw_enqueue_cmd(pcmdpriv, pcmd);
++
++exit:
++_func_exit_;
++	return res;
++
++}
++
++
++//adjust IEs for rtw_joinbss_cmd in WMM
++int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
++{
++	unsigned	int ielength=0;
++	unsigned int i, j;
++
++	i = 12; //after the fixed IE
++	while(i<in_len)
++	{
++		ielength = initial_out_len;
++
++		if(in_ie[i] == 0xDD && in_ie[i+2] == 0x00 && in_ie[i+3] == 0x50  && in_ie[i+4] == 0xF2 && in_ie[i+5] == 0x02 && i+5 < in_len) //WMM element ID and OUI
++		{
++
++			//Append WMM IE to the last index of out_ie
++			/*
++			for(j=i; j< i+(in_ie[i+1]+2); j++)
++			{
++				out_ie[ielength] = in_ie[j];
++				ielength++;
++			}
++			out_ie[initial_out_len+8] = 0x00; //force the QoS Info Field to be zero
++	                */
++
++                        for ( j = i; j < i + 9; j++ )
++                        {
++                            out_ie[ ielength] = in_ie[ j ];
++                            ielength++;
++                        }
++                        out_ie[ initial_out_len + 1 ] = 0x07;
++                        out_ie[ initial_out_len + 6 ] = 0x00;
++                        out_ie[ initial_out_len + 8 ] = 0x00;
++
++			break;
++		}
++
++		i+=(in_ie[i+1]+2); // to the next IE element
++	}
++
++	return ielength;
++
++}
++
++
++//
++// Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
++// Added by Annie, 2006-05-07.
++//
++// Search by BSSID,
++// Return Value:
++//		-1 		:if there is no pre-auth key in the  table
++//		>=0		:if there is pre-auth key, and   return the entry id
++//
++//
++
++static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
++{
++	struct security_priv *psecuritypriv=&Adapter->securitypriv;
++	int i=0;
++
++	do
++	{
++		if( ( psecuritypriv->PMKIDList[i].bUsed ) &&
++                    (  _rtw_memcmp( psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN ) == _TRUE ) )
++		{
++			break;
++		}
++		else
++		{
++			i++;
++			//continue;
++		}
++
++	}while(i<NUM_PMKID_CACHE);
++
++	if( i == NUM_PMKID_CACHE )
++	{
++		i = -1;// Could not find.
++	}
++	else
++	{
++		// There is one Pre-Authentication Key for the specific BSSID.
++	}
++
++	return (i);
++
++}
++
++//
++// Check the RSN IE length
++// If the RSN IE length <= 20, the RSN IE didn't include the PMKID information
++// 0-11th element in the array are the fixed IE
++// 12th element in the array is the IE
++// 13th element in the array is the IE length
++//
++
++static int rtw_append_pmkid(_adapter *Adapter,int iEntry, u8 *ie, uint ie_len)
++{
++	struct security_priv *psecuritypriv=&Adapter->securitypriv;
++
++	if(ie[13]<=20){
++		// The RSN IE didn't include the PMK ID, append the PMK information
++			ie[ie_len]=1;
++			ie_len++;
++			ie[ie_len]=0;	//PMKID count = 0x0100
++			ie_len++;
++			_rtw_memcpy(	&ie[ie_len], &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
++
++			ie_len+=16;
++			ie[13]+=18;//PMKID length = 2+16
++
++	}
++	return (ie_len);
++
++}
++sint rtw_restruct_sec_ie(_adapter *adapter,u8 *in_ie, u8 *out_ie, uint in_len)
++{
++	u8 authmode, securitytype, match;
++	u8 sec_ie[255], uncst_oui[4], bkup_ie[255];
++	u8 wpa_oui[4]={0x0, 0x50, 0xf2, 0x01};
++	uint 	ielength, cnt, remove_cnt;
++	int iEntry;
++
++	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
++	struct security_priv *psecuritypriv=&adapter->securitypriv;
++	uint 	ndisauthmode=psecuritypriv->ndisauthtype;
++	uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
++
++_func_enter_;
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
++		 ("+rtw_restruct_sec_ie: ndisauthmode=%d ndissecuritytype=%d\n",
++		  ndisauthmode, ndissecuritytype));
++
++	//copy fixed ie only
++	_rtw_memcpy(out_ie, in_ie,12);
++	ielength=12;
++	if((ndisauthmode==Ndis802_11AuthModeWPA)||(ndisauthmode==Ndis802_11AuthModeWPAPSK))
++			authmode=_WPA_IE_ID_;
++	if((ndisauthmode==Ndis802_11AuthModeWPA2)||(ndisauthmode==Ndis802_11AuthModeWPA2PSK))
++			authmode=_WPA2_IE_ID_;
++
++	if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
++	{
++		_rtw_memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
++
++		ielength += psecuritypriv->wps_ie_len;
++	}
++	else if((authmode==_WPA_IE_ID_)||(authmode==_WPA2_IE_ID_))
++	{
++		//copy RSN or SSN
++		_rtw_memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
++		/* debug for CONFIG_IEEE80211W
++		{
++			int jj;
++			printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
++			for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
++				printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
++			printk("\n");
++		}*/
++		ielength+=psecuritypriv->supplicant_ie[1]+2;
++		rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
++
++#ifdef CONFIG_DRVEXT_MODULE
++		drvext_report_sec_ie(&adapter->drvextpriv, authmode, sec_ie);
++#endif
++	}
++
++	iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
++	if(iEntry<0)
++	{
++		return ielength;
++	}
++	else
++	{
++		if(authmode == _WPA2_IE_ID_)
++		{
++			ielength=rtw_append_pmkid(adapter, iEntry, out_ie, ielength);
++		}
++	}
++
++_func_exit_;
++
++	return ielength;
++}
++
++void rtw_init_registrypriv_dev_network(	_adapter* adapter)
++{
++	struct registry_priv* pregistrypriv = &adapter->registrypriv;
++	struct eeprom_priv* peepriv = &adapter->eeprompriv;
++	WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
++	u8 *myhwaddr = myid(peepriv);
++
++_func_enter_;
++
++	_rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
++
++	_rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID));
++
++	pdev_network->Configuration.Length=sizeof(NDIS_802_11_CONFIGURATION);
++	pdev_network->Configuration.BeaconPeriod = 100;
++	pdev_network->Configuration.FHConfig.Length = 0;
++	pdev_network->Configuration.FHConfig.HopPattern = 0;
++	pdev_network->Configuration.FHConfig.HopSet = 0;
++	pdev_network->Configuration.FHConfig.DwellTime = 0;
++
++
++_func_exit_;
++
++}
++
++void rtw_update_registrypriv_dev_network(_adapter* adapter)
++{
++	int sz=0;
++	struct registry_priv* pregistrypriv = &adapter->registrypriv;
++	WLAN_BSSID_EX    *pdev_network = &pregistrypriv->dev_network;
++	struct	security_priv*	psecuritypriv = &adapter->securitypriv;
++	struct	wlan_network	*cur_network = &adapter->mlmepriv.cur_network;
++	//struct	xmit_priv	*pxmitpriv = &adapter->xmitpriv;
++
++_func_enter_;
++
++#if 0
++	pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
++	pxmitpriv->vcs = pregistrypriv->vcs_type;
++	pxmitpriv->vcs_type = pregistrypriv->vcs_type;
++	//pxmitpriv->rts_thresh = pregistrypriv->rts_thresh;
++	pxmitpriv->frag_len = pregistrypriv->frag_thresh;
++
++	adapter->qospriv.qos_option = pregistrypriv->wmm_enable;
++#endif
++
++	pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; // adhoc no 802.1x
++
++	pdev_network->Rssi = 0;
++
++	switch(pregistrypriv->wireless_mode)
++	{
++		case WIRELESS_11B:
++			pdev_network->NetworkTypeInUse = (Ndis802_11DS);
++			break;
++		case WIRELESS_11G:
++		case WIRELESS_11BG:
++		case WIRELESS_11_24N:
++		case WIRELESS_11G_24N:
++		case WIRELESS_11BG_24N:
++			pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
++			break;
++		case WIRELESS_11A:
++		case WIRELESS_11A_5N:
++			pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
++			break;
++		case WIRELESS_11ABGN:
++			if(pregistrypriv->channel > 14)
++				pdev_network->NetworkTypeInUse = (Ndis802_11OFDM5);
++			else
++				pdev_network->NetworkTypeInUse = (Ndis802_11OFDM24);
++			break;
++		default :
++			// TODO
++			break;
++	}
++
++	pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("pregistrypriv->channel=%d, pdev_network->Configuration.DSConfig=0x%x\n", pregistrypriv->channel, pdev_network->Configuration.DSConfig));
++
++	if(cur_network->network.InfrastructureMode == Ndis802_11IBSS)
++		pdev_network->Configuration.ATIMWindow = (0);
++
++	pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
++
++	// 1. Supported rates
++	// 2. IE
++
++	//rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; // will be called in rtw_generate_ie
++	sz = rtw_generate_ie(pregistrypriv);
++
++	pdev_network->IELength = sz;
++
++	pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX  *)pdev_network);
++
++	//notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd();
++	//pdev_network->IELength = cpu_to_le32(sz);
++
++_func_exit_;
++
++}
++
++void rtw_get_encrypt_decrypt_from_registrypriv(_adapter* adapter)
++{
++_func_enter_;
++
++
++_func_exit_;
++
++}
++
++//the fucntion is at passive_level
++void rtw_joinbss_reset(_adapter *padapter)
++{
++	u8	threshold;
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++
++#ifdef CONFIG_80211N_HT
++	struct ht_priv		*phtpriv = &pmlmepriv->htpriv;
++#endif
++
++	//todo: if you want to do something io/reg/hw setting before join_bss, please add code here
++
++
++
++
++#ifdef CONFIG_80211N_HT
++
++	pmlmepriv->num_FortyMHzIntolerant = 0;
++
++	pmlmepriv->num_sta_no_ht = 0;
++
++	phtpriv->ampdu_enable = _FALSE;//reset to disabled
++
++#ifdef CONFIG_USB_HCI
++	// TH=1 => means that invalidate usb rx aggregation
++	// TH=0 => means that validate usb rx aggregation, use init value.
++	if(phtpriv->ht_option)
++	{
++		if(padapter->registrypriv.wifi_spec==1)
++			threshold = 1;
++		else
++			threshold = 0;
++		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
++	}
++	else
++	{
++		threshold = 1;
++		rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
++	}
++#endif
++
++#endif
++
++}
++
++
++#ifdef CONFIG_80211N_HT
++
++//the fucntion is >= passive_level
++unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
++{
++	u32 ielen, out_len;
++	unsigned char *p, *pframe;
++	struct rtw_ieee80211_ht_cap ht_capie;
++	unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	struct qos_priv   	*pqospriv= &pmlmepriv->qospriv;
++	struct ht_priv		*phtpriv = &pmlmepriv->htpriv;
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++	u8 cbw40_enable = 0;
++
++	phtpriv->ht_option = _FALSE;
++
++	p = rtw_get_ie(in_ie+12, _HT_CAPABILITY_IE_, &ielen, in_len-12);
++
++	if(p && ielen>0)
++	{
++		if(pqospriv->qos_option == 0)
++		{
++			out_len = *pout_len;
++			pframe = rtw_set_ie(out_ie+out_len, _VENDOR_SPECIFIC_IE_,
++								_WMM_IE_Length_, WMM_IE, pout_len);
++
++			pqospriv->qos_option = 1;
++		}
++
++		out_len = *pout_len;
++
++		_rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
++
++		ht_capie.cap_info =  IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_TX_STBC |
++							IEEE80211_HT_CAP_DSSSCCK40;
++		//if insert module set only support 20MHZ, don't add the 40MHZ and SGI_40
++		if( channel > 14 )
++		{
++			if( pregpriv->cbw40_enable & BIT(1) )
++				cbw40_enable = 1;
++		}
++		else
++			if( pregpriv->cbw40_enable & BIT(0) )
++				cbw40_enable = 1;
++
++		if ( cbw40_enable != 0 )
++			ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH | IEEE80211_HT_CAP_SGI_40;
++
++
++
++		{
++			u32 rx_packet_offset, max_recvbuf_sz;
++			rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
++			rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
++			//if(max_recvbuf_sz-rx_packet_offset>(8191-256)) {
++			//	DBG_871X("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__);
++			//	ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU;
++			//}
++		}
++
++		ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
++
++		if(padapter->securitypriv.dot11PrivacyAlgrthm == _AES_ )
++			ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
++		else
++			ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
++
++
++		pframe = rtw_set_ie(out_ie+out_len, _HT_CAPABILITY_IE_,
++							sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, pout_len);
++
++
++		//_rtw_memcpy(out_ie+out_len, p, ielen+2);//gtest
++		//*pout_len = *pout_len + (ielen+2);
++
++
++		phtpriv->ht_option = _TRUE;
++
++		p = rtw_get_ie(in_ie+12, _HT_ADD_INFO_IE_, &ielen, in_len-12);
++		if(p && (ielen==sizeof(struct ieee80211_ht_addt_info)))
++		{
++			out_len = *pout_len;
++			pframe = rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2 , pout_len);
++		}
++
++	}
++
++	return (phtpriv->ht_option);
++
++}
++
++//the fucntion is > passive_level (in critical_section)
++void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
++{
++	u8 *p, max_ampdu_sz;
++	int len;
++	//struct sta_info *bmc_sta, *psta;
++	struct rtw_ieee80211_ht_cap *pht_capie;
++	struct ieee80211_ht_addt_info *pht_addtinfo;
++	//struct recv_reorder_ctrl *preorder_ctrl;
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	struct ht_priv		*phtpriv = &pmlmepriv->htpriv;
++	//struct recv_priv *precvpriv = &padapter->recvpriv;
++	struct registry_priv *pregistrypriv = &padapter->registrypriv;
++	//struct wlan_network *pcur_network = &(pmlmepriv->cur_network);;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 cbw40_enable=0;
++
++	if(!phtpriv->ht_option)
++		return;
++
++	if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
++		return;
++
++	DBG_871X("+rtw_update_ht_cap()\n");
++
++	//maybe needs check if ap supports rx ampdu.
++	if((phtpriv->ampdu_enable==_FALSE) &&(pregistrypriv->ampdu_enable==1))
++	{
++		//In the wifi cert. test, the test Lab should turn off the AP's RX AMPDU. client doen't need to close the TX AMPDU
++		/*if(pregistrypriv->wifi_spec==1)
++		{
++			phtpriv->ampdu_enable = _FALSE;
++		}
++		else*/
++		{
++			phtpriv->ampdu_enable = _TRUE;
++		}
++	}
++	else if(pregistrypriv->ampdu_enable==2)
++	{
++		phtpriv->ampdu_enable = _TRUE;
++	}
++
++
++	//check Max Rx A-MPDU Size
++	len = 0;
++	p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs));
++	if(p && len>0)
++	{
++		pht_capie = (struct rtw_ieee80211_ht_cap *)(p+2);
++		max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
++		max_ampdu_sz = 1 << (max_ampdu_sz+3); // max_ampdu_sz (kbytes);
++
++		//DBG_871X("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz);
++		phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
++
++	}
++
++
++	len=0;
++	p = rtw_get_ie(pie+sizeof (NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len-sizeof (NDIS_802_11_FIXED_IEs));
++	if(p && len>0)
++	{
++		pht_addtinfo = (struct ieee80211_ht_addt_info *)(p+2);
++		//todo:
++	}
++
++	if( channel > 14 )
++	{
++		if( pregistrypriv->cbw40_enable & BIT(1) )
++			cbw40_enable = 1;
++	}
++	else
++		if( pregistrypriv->cbw40_enable & BIT(0) )
++			cbw40_enable = 1;
++
++
++	//update cur_bwmode & cur_ch_offset
++	if ((cbw40_enable) &&
++		(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
++		(pmlmeinfo->HT_info.infos[0] & BIT(2)))
++	{
++		int i;
++		u8	rf_type;
++
++		rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
++
++		//update the MCS rates
++		for (i = 0; i < 16; i++)
++		{
++			if((rf_type == RF_1T1R) || (rf_type == RF_1T2R))
++			{
++				pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
++			}
++			else
++			{
++				#ifdef CONFIG_DISABLE_MCS13TO15
++				if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1 )
++				{
++					pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R_MCS13TO15_OFF[i];
++				}
++				else
++					pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
++				#else
++				pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_2R[i];
++				#endif //CONFIG_DISABLE_MCS13TO15
++			}
++			#ifdef RTL8192C_RECONFIG_TO_1T1R
++			{
++				pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
++			}
++			#endif
++
++			if(pregistrypriv->special_rf_path)
++				pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
++
++		}
++		//switch to the 40M Hz mode accoring to the AP
++		pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
++		switch ((pmlmeinfo->HT_info.infos[0] & 0x3))
++		{
++			case HT_EXTCHNL_OFFSET_UPPER:
++				pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
++				break;
++
++			case HT_EXTCHNL_OFFSET_LOWER:
++				pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
++				break;
++
++			default:
++				pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++				break;
++		}
++	}
++
++	//
++	// Config SM Power Save setting
++	//
++	pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
++	if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
++	{
++		/*u8 i;
++		//update the MCS rates
++		for (i = 0; i < 16; i++)
++		{
++			pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
++		}*/
++		DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
++	}
++
++	//
++	// Config current HT Protection mode.
++	//
++	pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
++
++
++
++#if 0 //move to rtw_update_sta_info_client()
++	//for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
++	//if A-MPDU Rx is enabled, reseting  rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff
++	//todo: check if AP can send A-MPDU packets
++	bmc_sta = rtw_get_bcmc_stainfo(padapter);
++	if(bmc_sta)
++	{
++		for(i=0; i < 16 ; i++)
++		{
++			//preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
++			preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
++			preorder_ctrl->enable = _FALSE;
++			preorder_ctrl->indicate_seq = 0xffff;
++			#ifdef DBG_RX_SEQ
++			DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
++				preorder_ctrl->indicate_seq);
++			#endif
++			preorder_ctrl->wend_b= 0xffff;
++			preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
++		}
++	}
++
++	psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
++	if(psta)
++	{
++		for(i=0; i < 16 ; i++)
++		{
++			//preorder_ctrl = &precvpriv->recvreorder_ctrl[i];
++			preorder_ctrl = &psta->recvreorder_ctrl[i];
++			preorder_ctrl->enable = _FALSE;
++			preorder_ctrl->indicate_seq = 0xffff;
++			#ifdef DBG_RX_SEQ
++			DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
++				preorder_ctrl->indicate_seq);
++			#endif
++			preorder_ctrl->wend_b= 0xffff;
++			preorder_ctrl->wsize_b = 64;//max_ampdu_sz;//ex. 32(kbytes) -> wsize_b=32
++		}
++	}
++#endif
++
++}
++
++void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe)
++{
++	u8 issued;
++	int priority;
++	struct sta_info *psta=NULL;
++	struct ht_priv	*phtpriv;
++	struct pkt_attrib *pattrib =&pxmitframe->attrib;
++	s32 bmcst = IS_MCAST(pattrib->ra);
++
++	if(bmcst || (padapter->mlmepriv.LinkDetectInfo.bTxBusyTraffic == _FALSE))
++		return;
++
++	priority = pattrib->priority;
++
++	if (pattrib->psta)
++		psta = pattrib->psta;
++	else
++	{
++		DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
++		psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
++	}
++
++	if(psta==NULL)
++	{
++		DBG_871X("%s, psta==NUL\n", __func__);
++		return;
++	}
++
++	if(!(psta->state &_FW_LINKED))
++	{
++		DBG_871X("%s, psta->state(0x%x) != _FW_LINKED\n", __func__, psta->state);
++		return;
++	}
++
++
++	phtpriv = &psta->htpriv;
++
++	if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
++	{
++		issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
++		issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
++
++		if(0==issued)
++		{
++			DBG_871X("rtw_issue_addbareq_cmd, p=%d\n", priority);
++			psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
++			rtw_addbareq_cmd(padapter,(u8) priority, pattrib->ra);
++		}
++	}
++
++}
++
++#endif
++
++#ifdef CONFIG_LAYER2_ROAMING
++inline void rtw_set_roaming(_adapter *adapter, u8 to_roaming)
++{
++	if (to_roaming == 0)
++		adapter->mlmepriv.to_join = _FALSE;
++	adapter->mlmepriv.to_roaming = to_roaming;
++}
++
++inline u8 rtw_to_roaming(_adapter *adapter)
++{
++	return adapter->mlmepriv.to_roaming;
++}
++
++void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
++{
++	_irqL irqL;
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++
++	_enter_critical_bh(&pmlmepriv->lock, &irqL);
++	_rtw_roaming(padapter, tgt_network);
++	_exit_critical_bh(&pmlmepriv->lock, &irqL);
++}
++void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
++{
++	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
++	int do_join_r;
++
++	struct wlan_network *pnetwork;
++
++	if(tgt_network != NULL)
++		pnetwork = tgt_network;
++	else
++		pnetwork = &pmlmepriv->cur_network;
++
++	if(0 < rtw_to_roaming(padapter)) {
++		DBG_871X("roaming from %s("MAC_FMT"), length:%d\n",
++				pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress),
++				pnetwork->network.Ssid.SsidLength);
++		_rtw_memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));
++
++		pmlmepriv->assoc_by_bssid = _FALSE;
++
++		while(1) {
++			if( _SUCCESS==(do_join_r=rtw_do_join(padapter)) ) {
++				break;
++			} else {
++				DBG_871X("roaming do_join return %d\n", do_join_r);
++				pmlmepriv->to_roaming--;
++
++				if(0< rtw_to_roaming(padapter)) {
++					continue;
++				} else {
++					DBG_871X("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__,__LINE__);
++					rtw_indicate_disconnect(padapter);
++					break;
++				}
++			}
++		}
++	}
++
++}
++#endif
++
++#ifdef CONFIG_CONCURRENT_MODE
++sint rtw_buddy_adapter_up(_adapter *padapter)
++{
++	sint res = _FALSE;
++
++	if(padapter == NULL)
++		return res;
++
++
++	if(padapter->pbuddy_adapter == NULL)
++	{
++		res = _FALSE;
++	}
++	else if( (padapter->pbuddy_adapter->bDriverStopped) || (padapter->pbuddy_adapter->bSurpriseRemoved) ||
++		(padapter->pbuddy_adapter->bup == _FALSE) || (padapter->pbuddy_adapter->hw_init_completed == _FALSE))
++	{
++		res = _FALSE;
++	}
++	else
++	{
++		res = _TRUE;
++	}
++
++	return res;
++
++}
++
++sint check_buddy_fwstate(_adapter *padapter, sint state)
++{
++	if(padapter == NULL)
++		return _FALSE;
++
++	if(padapter->pbuddy_adapter == NULL)
++		return _FALSE;
++
++	if ((state == WIFI_FW_NULL_STATE) &&
++		(padapter->pbuddy_adapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
++		return _TRUE;
++
++	if (padapter->pbuddy_adapter->mlmepriv.fw_state & state)
++		return _TRUE;
++
++	return _FALSE;
++}
++#endif //CONFIG_CONCURRENT_MODE
+--- /dev/null
++++ b/drivers/net/wireless/realtek/rtl8192cu/core/rtw_mlme_ext.c
+@@ -0,0 +1,13599 @@
++/******************************************************************************
++ *
++ * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of version 2 of the GNU General Public License 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
++ *
++ *
++ ******************************************************************************/
++#define _RTW_MLME_EXT_C_
++
++#include <drv_conf.h>
++#include <osdep_service.h>
++#include <drv_types.h>
++#include <wifi.h>
++#include <rtw_mlme_ext.h>
++#include <wlan_bssdef.h>
++#include <mlme_osdep.h>
++#include <recv_osdep.h>
++
++struct mlme_handler mlme_sta_tbl[]={
++	{WIFI_ASSOCREQ,		"OnAssocReq",	&OnAssocReq},
++	{WIFI_ASSOCRSP,		"OnAssocRsp",	&OnAssocRsp},
++	{WIFI_REASSOCREQ,	"OnReAssocReq",	&OnAssocReq},
++	{WIFI_REASSOCRSP,	"OnReAssocRsp",	&OnAssocRsp},
++	{WIFI_PROBEREQ,		"OnProbeReq",	&OnProbeReq},
++	{WIFI_PROBERSP,		"OnProbeRsp",		&OnProbeRsp},
++
++	/*----------------------------------------------------------
++					below 2 are reserved
++	-----------------------------------------------------------*/
++	{0,					"DoReserved",		&DoReserved},
++	{0,					"DoReserved",		&DoReserved},
++	{WIFI_BEACON,		"OnBeacon",		&OnBeacon},
++	{WIFI_ATIM,			"OnATIM",		&OnAtim},
++	{WIFI_DISASSOC,		"OnDisassoc",		&OnDisassoc},
++	{WIFI_AUTH,			"OnAuth",		&OnAuthClient},
++	{WIFI_DEAUTH,		"OnDeAuth",		&OnDeAuth},
++	{WIFI_ACTION,		"OnAction",		&OnAction},
++};
++
++#ifdef _CONFIG_NATIVEAP_MLME_
++struct mlme_handler mlme_ap_tbl[]={
++	{WIFI_ASSOCREQ,		"OnAssocReq",	&OnAssocReq},
++	{WIFI_ASSOCRSP,		"OnAssocRsp",	&OnAssocRsp},
++	{WIFI_REASSOCREQ,	"OnReAssocReq",	&OnAssocReq},
++	{WIFI_REASSOCRSP,	"OnReAssocRsp",	&OnAssocRsp},
++	{WIFI_PROBEREQ,		"OnProbeReq",	&OnProbeReq},
++	{WIFI_PROBERSP,		"OnProbeRsp",		&OnProbeRsp},
++
++	/*----------------------------------------------------------
++					below 2 are reserved
++	-----------------------------------------------------------*/
++	{0,					"DoReserved",		&DoReserved},
++	{0,					"DoReserved",		&DoReserved},
++	{WIFI_BEACON,		"OnBeacon",		&OnBeacon},
++	{WIFI_ATIM,			"OnATIM",		&OnAtim},
++	{WIFI_DISASSOC,		"OnDisassoc",		&OnDisassoc},
++	{WIFI_AUTH,			"OnAuth",		&OnAuth},
++	{WIFI_DEAUTH,		"OnDeAuth",		&OnDeAuth},
++	{WIFI_ACTION,		"OnAction",		&OnAction},
++};
++#endif
++
++struct action_handler OnAction_tbl[]={
++	{RTW_WLAN_CATEGORY_SPECTRUM_MGMT,	 "ACTION_SPECTRUM_MGMT", on_action_spct},
++	{RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
++	{RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
++	{RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
++	{RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
++	{RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
++	{RTW_WLAN_CATEGORY_FT, "ACTION_FT",	&DoReserved},
++	{RTW_WLAN_CATEGORY_HT,	"ACTION_HT",	&OnAction_ht},
++#ifdef CONFIG_IEEE80211W
++	{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
++#else
++	{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
++#endif //CONFIG_IEEE80211W
++	//add for CONFIG_IEEE80211W
++	{RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
++	{RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
++	{RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
++	{RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
++};
++
++
++u8	null_addr[ETH_ALEN]= {0,0,0,0,0,0};
++
++/**************************************************
++OUI definitions for the vendor specific IE
++***************************************************/
++unsigned char	RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
++unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
++unsigned char	WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
++unsigned char	P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
++unsigned char	WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
++
++unsigned char	WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
++unsigned char	WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
++
++unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
++unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
++
++extern unsigned char REALTEK_96B_IE[];
++
++/********************************************************
++MCS rate definitions
++*********************************************************/
++#ifdef CONFIG_DISABLE_MCS13TO15
++unsigned char	MCS_rate_2R_MCS13TO15_OFF[16] = {0xff, 0x1f, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
++unsigned char	MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
++#else //CONFIG_DISABLE_MCS13TO15
++unsigned char	MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
++#endif //CONFIG_DISABLE_MCS13TO15
++unsigned char	MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
++
++/********************************************************
++ChannelPlan definitions
++*********************************************************/
++/*static RT_CHANNEL_PLAN	DefaultChannelPlan[RT_CHANNEL_DOMAIN_MAX] = {
++	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},32},					// 0x00, RT_CHANNEL_DOMAIN_FCC
++	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},31},						// 0x01, RT_CHANNEL_DOMAIN_IC
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32},						// 0x02, RT_CHANNEL_DOMAIN_ETSI
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x03, RT_CHANNEL_DOMAIN_SPAIN
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x04, RT_CHANNEL_DOMAIN_FRANCE
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x05, RT_CHANNEL_DOMAIN_MKK
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x06, RT_CHANNEL_DOMAIN_MKK1
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21},																// 0x07, RT_CHANNEL_DOMAIN_ISRAEL
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},															// 0x08, RT_CHANNEL_DOMAIN_TELEC
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14},																				// 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},																					// 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
++	{{1,2,3,4,5,6,7,8,9,10,11,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},26},									// 0x0B, RT_CHANNEL_DOMAIN_TAIWAN
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,149,153,157,161,165},18},																// 0x0C, RT_CHANNEL_DOMAIN_CHINA
++	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24},												// 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
++	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},31},						// 0x0E, RT_CHANNEL_DOMAIN_KOREA
++	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19},																	// 0x0F, RT_CHANNEL_DOMAIN_TURKEY
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},32},						// 0x10, RT_CHANNEL_DOMAIN_JAPAN
++	{{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,149,153,157,161,165},20},															// 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48},17},																		// 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},37},	// 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
++	{{1,2,3,4,5,6,7,8,9,10,11,56,60,64,149,153,157,161,165},19},																// 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
++};*/
++
++static RT_CHANNEL_PLAN_2G	RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},		// 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13},13},		// 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1
++	{{1,2,3,4,5,6,7,8,9,10,11},11},			// 0x02, RT_CHANNEL_DOMAIN_2G_FCC1
++	{{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14},	// 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1
++	{{10,11,12,13},4},						// 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2
++	{{},0},									// 0x05, RT_CHANNEL_DOMAIN_2G_NULL
++};
++
++static RT_CHANNEL_PLAN_5G	RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
++	{{},0},																					// 0x00, RT_CHANNEL_DOMAIN_5G_NULL
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19},						// 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24},	// 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,149,153,157,161,165},22},			// 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165},24},	// 0x04, RT_CHANNEL_DOMAIN_5G_FCC1
++	{{36,40,44,48,149,153,157,161,165},9},														// 0x05, RT_CHANNEL_DOMAIN_5G_FCC2
++	{{36,40,44,48,52,56,60,64,149,153,157,161,165},13},											// 0x06, RT_CHANNEL_DOMAIN_5G_FCC3
++	{{36,40,44,48,52,56,60,64,149,153,157,161},12},												// 0x07, RT_CHANNEL_DOMAIN_5G_FCC4
++	{{149,153,157,161,165},5},																	// 0x08, RT_CHANNEL_DOMAIN_5G_FCC5
++	{{36,40,44,48,52,56,60,64},8},																// 0x09, RT_CHANNEL_DOMAIN_5G_FCC6
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},20},					// 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,149,153,157,161,165},20},					// 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140},19},						// 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1
++	{{36,40,44,48,52,56,60,64},8},																// 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2
++	{{100,104,108,112,116,120,124,128,132,136,140},11},											// 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3
++	{{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15},								// 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1
++	{{56,60,64,149,153,157,161,165},8},															// 0x10, RT_CHANNEL_DOMAIN_5G_NCC2
++
++	//===== Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition =====
++	{{36,40,44,48,52,56,60,64,100,104,108,112,116,132,136,140,149,153,157,161,165},21},				// 0x11, RT_CHANNEL_DOMAIN_5G_FCC
++	{{36,40,44,48},4},																			// 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS
++	{{36,40,44,48,149,153,157,161},8},																// 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS
++};
++
++static RT_CHANNEL_PLAN_MAP	RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
++	//===== 0x00 ~ 0x1F , Old Define =====
++	{0x02,0x11},	//0x00, RT_CHANNEL_DOMAIN_FCC
++	{0x02,0x0A},	//0x01, RT_CHANNEL_DOMAIN_IC
++	{0x01,0x01},	//0x02, RT_CHANNEL_DOMAIN_ETSI
++	{0x01,0x00},	//0x03, RT_CHANNEL_DOMAIN_SPAIN
++	{0x01,0x00},	//0x04, RT_CHANNEL_DOMAIN_FRANCE
++	{0x03,0x00},	//0x05, RT_CHANNEL_DOMAIN_MKK
++	{0x03,0x00},	//0x06, RT_CHANNEL_DOMAIN_MKK1
++	{0x01,0x09},	//0x07, RT_CHANNEL_DOMAIN_ISRAEL
++	{0x03,0x09},	//0x08, RT_CHANNEL_DOMAIN_TELEC
++	{0x03,0x00},	//0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
++	{0x00,0x00},	//0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13
++	{0x02,0x0F},	//0x0B, RT_CHANNEL_DOMAIN_TAIWAN
++	{0x01,0x08},	//0x0C, RT_CHANNEL_DOMAIN_CHINA
++	{0x02,0x06},	//0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO
++	{0x02,0x0B},	//0x0E, RT_CHANNEL_DOMAIN_KOREA
++	{0x02,0x09},	//0x0F, RT_CHANNEL_DOMAIN_TURKEY
++	{0x01,0x01},	//0x10, RT_CHANNEL_DOMAIN_JAPAN
++	{0x02,0x05},	//0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS
++	{0x01,0x12},	//0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
++	{0x00,0x04},	//0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
++	{0x02,0x10},	//0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS
++	{0x00,0x12},	//0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS
++	{0x00,0x13},	//0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS
++	{0x03,0x12},	//0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS
++	{0x05,0x08},	//0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS
++	{0x02,0x08},	//0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS
++	{0x00,0x00},	//0x1A,
++	{0x00,0x00},	//0x1B,
++	{0x00,0x00},	//0x1C,
++	{0x00,0x00},	//0x1D,
++	{0x00,0x00},	//0x1E,
++	{0x05,0x04},	//0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G
++	//===== 0x20 ~ 0x7F ,New Define =====
++	{0x00,0x00},	//0x20, RT_CHANNEL_DOMAIN_WORLD_NULL
++	{0x01,0x00},	//0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL
++	{0x02,0x00},	//0x22, RT_CHANNEL_DOMAIN_FCC1_NULL
++	{0x03,0x00},	//0x23, RT_CHANNEL_DOMAIN_MKK1_NULL
++	{0x04,0x00},	//0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL
++	{0x02,0x04},	//0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1
++	{0x00,0x01},	//0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1
++	{0x03,0x0C},	//0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1
++	{0x00,0x0B},	//0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1
++	{0x00,0x05},	//0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2
++	{0x00,0x00},	//0x2A,
++	{0x00,0x00},	//0x2B,
++	{0x00,0x00},	//0x2C,
++	{0x00,0x00},	//0x2D,
++	{0x00,0x00},	//0x2E,
++	{0x00,0x00},	//0x2F,
++	{0x00,0x06},	//0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3
++	{0x00,0x07},	//0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4
++	{0x00,0x08},	//0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5
++	{0x00,0x09},	//0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6
++	{0x02,0x0A},	//0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7
++	{0x00,0x02},	//0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2
++	{0x00,0x03},	//0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3
++	{0x03,0x0D},	//0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2
++	{0x03,0x0E},	//0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3
++	{0x02,0x0F},	//0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1
++	{0x00,0x00},	//0x3A,
++	{0x00,0x00},	//0x3B,
++	{0x00,0x00},	//0x3C,
++	{0x00,0x00},	//0x3D,
++	{0x00,0x00},	//0x3E,
++	{0x00,0x00},	//0x3F,
++	{0x02,0x10},	//0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2
++};
++
++static RT_CHANNEL_PLAN_MAP	RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03,0x02}; //use the conbination for max channel numbers
++
++/*
++ * Search the @param ch in given @param ch_set
++ * @ch_set: the given channel set
++ * @ch: the given channel number
++ *
++ * return the index of channel_num in channel_set, -1 if not found
++ */
++int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
++{
++	int i;
++	for(i=0;ch_set[i].ChannelNum!=0;i++){
++		if(ch == ch_set[i].ChannelNum)
++			break;
++	}
++
++	if(i >= ch_set[i].ChannelNum)
++		return -1;
++	return i;
++}
++
++/*
++ * Check the @param ch is fit with setband setting of @param adapter
++ * @adapter: the given adapter
++ * @ch: the given channel number
++ *
++ * return _TRUE when check valid, _FALSE not valid
++ */
++bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
++{
++	if (adapter->setband == GHZ24_50 /* 2.4G and 5G */
++		|| (adapter->setband == GHZ_24 && ch < 35) /* 2.4G only */
++		|| (adapter->setband == GHZ_50 && ch > 35) /* 5G only */
++	) {
++		return _TRUE;
++	}
++	return _FALSE;
++}
++
++/****************************************************************************
++
++Following are the initialization functions for WiFi MLME
++
++*****************************************************************************/
++
++int init_hw_mlme_ext(_adapter *padapter)
++{
++	struct	mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++
++	//set_opmode_cmd(padapter, infra_client_with_mlme);//removed
++
++	set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
++
++	return _SUCCESS;
++}
++
++static void init_mlme_ext_priv_value(_adapter* padapter)
++{
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	//unsigned char default_channel_set[MAX_CHANNEL_NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 0};
++	unsigned char	mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
++	unsigned char	mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
++
++	ATOMIC_SET(&pmlmeext->event_seq, 0);
++	pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
++#ifdef CONFIG_IEEE80211W
++	pmlmeext->sa_query_seq = 0;
++	pmlmeext->mgnt_80211w_IPN=0;
++	pmlmeext->mgnt_80211w_IPN_rx=0;
++#endif //CONFIG_IEEE80211W
++	pmlmeext->cur_channel = padapter->registrypriv.channel;
++	pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
++	pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++
++	pmlmeext->retry = 0;
++
++	pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
++
++	//_rtw_memcpy(pmlmeext->channel_set, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Channel, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Len);
++	//_rtw_memcpy(pmlmeext->channel_set, default_channel_set, MAX_CHANNEL_NUM);
++	_rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
++	_rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
++
++	if(pmlmeext->cur_channel > 14)
++		pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
++	else
++		pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
++
++	pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
++	pmlmeext->sitesurvey_res.channel_idx = 0;
++	pmlmeext->sitesurvey_res.bss_cnt = 0;
++	pmlmeext->scan_abort = _FALSE;
++
++	pmlmeinfo->state = WIFI_FW_NULL_STATE;
++	pmlmeinfo->reauth_count = 0;
++	pmlmeinfo->reassoc_count = 0;
++	pmlmeinfo->link_count = 0;
++	pmlmeinfo->auth_seq = 0;
++	pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
++	pmlmeinfo->key_index = 0;
++	pmlmeinfo->iv = 0;
++
++	pmlmeinfo->enc_algo = _NO_PRIVACY_;
++	pmlmeinfo->authModeToggle = 0;
++
++	_rtw_memset(pmlmeinfo->chg_txt, 0, 128);
++
++	pmlmeinfo->slotTime = SHORT_SLOT_TIME;
++	pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
++
++	pmlmeinfo->dialogToken = 0;
++
++	pmlmeext->action_public_rxseq = 0xffff;
++	pmlmeext->action_public_dialog_token = 0xff;
++}
++
++static int has_channel(RT_CHANNEL_INFO *channel_set,
++					   u8 chanset_size,
++					   u8 chan) {
++	int i;
++
++	for (i = 0; i < chanset_size; i++) {
++		if (channel_set[i].ChannelNum == chan) {
++			return 1;
++		}
++	}
++
++	return 0;
++}
++
++static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
++							  u8 chanset_size,
++							  struct p2p_channels *channel_list) {
++
++	struct p2p_oper_class_map op_class[] = {
++		{ IEEE80211G,  81,   1,  13,  1, BW20 },
++		{ IEEE80211G,  82,  14,  14,  1, BW20 },
++#if 0 /* Do not enable HT40 on 2 GHz */
++		{ IEEE80211G,  83,   1,   9,  1, BW40PLUS },
++		{ IEEE80211G,  84,   5,  13,  1, BW40MINUS },
++#endif
++		{ IEEE80211A, 115,  36,  48,  4, BW20 },
++		{ IEEE80211A, 116,  36,  44,  8, BW40PLUS },
++		{ IEEE80211A, 117,  40,  48,  8, BW40MINUS },
++		{ IEEE80211A, 124, 149, 161,  4, BW20 },
++		{ IEEE80211A, 125, 149, 169,  4, BW20 },
++		{ IEEE80211A, 126, 149, 157,  8, BW40PLUS },
++		{ IEEE80211A, 127, 153, 161,  8, BW40MINUS },
++		{ -1, 0, 0, 0, 0, BW20 }
++	};
++
++	int cla, op;
++
++	cla = 0;
++
++	for (op = 0; op_class[op].op_class; op++) {
++		u8 ch;
++		struct p2p_oper_class_map *o = &op_class[op];
++		struct p2p_reg_class *reg = NULL;
++
++		for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
++			if (!has_channel(channel_set, chanset_size, ch)) {
++				continue;
++			}
++
++			if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
++				continue;
++
++			if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
++				((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
++				continue;
++
++			if (reg == NULL) {
++				reg = &channel_list->reg_class[cla];
++				cla++;
++				reg->reg_class = o->op_class;
++				reg->channels = 0;
++			}
++			reg->channel[reg->channels] = ch;
++			reg->channels++;
++		}
++	}
++	channel_list->reg_classes = cla;
++
++}
++
++static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
++{
++	u8	index,chanset_size = 0;
++	u8	b5GBand = _FALSE, b2_4GBand = _FALSE;
++	u8	Index2G = 0, Index5G=0;
++
++	_rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
++
++	if(ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
++	{
++		DBG_871X("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
++		return chanset_size;
++	}
++
++	if(padapter->registrypriv.wireless_mode & WIRELESS_11G)
++	{
++		b2_4GBand = _TRUE;
++		if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
++			Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
++		else
++			Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
++	}
++
++	if(padapter->registrypriv.wireless_mode & WIRELESS_11A)
++	{
++		b5GBand = _TRUE;
++		if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
++			Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
++		else
++			Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
++	}
++
++	if(b2_4GBand)
++	{
++		for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
++		{
++			channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
++
++			if(RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) //Channel 1~11 is active, and 12~14 is passive
++			{
++				if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
++					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
++				else if((channel_set[chanset_size].ChannelNum  >= 12 && channel_set[chanset_size].ChannelNum  <= 14))
++					channel_set[chanset_size].ScanType  = SCAN_PASSIVE;
++			}
++			else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
++				RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
++				RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)// channel 12~13, passive scan
++			{
++				if(channel_set[chanset_size].ChannelNum <= 11)
++					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
++				else
++					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
++			}
++			else
++			{
++				channel_set[chanset_size].ScanType = SCAN_ACTIVE;
++			}
++
++			chanset_size++;
++		}
++	}
++
++	if(b5GBand)
++	{
++		for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
++		{
++#ifdef CONFIG_DFS
++			channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
++			if ( channel_set[chanset_size].ChannelNum <= 48
++				|| channel_set[chanset_size].ChannelNum >= 149 )
++			{
++				if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
++					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
++				else
++					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
++			}
++			else
++			{
++				channel_set[chanset_size].ScanType = SCAN_PASSIVE;
++			}
++			chanset_size++;
++#else /* CONFIG_DFS */
++			if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
++				|| RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
++				channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
++				if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)//passive scan for all 5G channels
++					channel_set[chanset_size].ScanType = SCAN_PASSIVE;
++				else
++					channel_set[chanset_size].ScanType = SCAN_ACTIVE;
++				DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
++				chanset_size++;
++			}
++#endif /* CONFIG_DFS */
++		}
++	}
++
++	return chanset_size;
++}
++
++int	init_mlme_ext_priv(_adapter* padapter)
++{
++	int	res = _SUCCESS;
++	struct registry_priv* pregistrypriv = &padapter->registrypriv;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	// We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
++	//_rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv));
++
++	pmlmeext->padapter = padapter;
++
++	//fill_fwpriv(padapter, &(pmlmeext->fwpriv));
++
++	init_mlme_ext_priv_value(padapter);
++	pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
++
++	init_mlme_ext_timer(padapter);
++
++#ifdef CONFIG_AP_MODE
++	init_mlme_ap_info(padapter);
++#endif
++
++	pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
++	init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
++
++	pmlmeext->chan_scan_time = SURVEY_TO;
++	pmlmeext->mlmeext_init = _TRUE;
++
++
++#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
++	pmlmeext->active_keep_alive_check = _TRUE;
++#endif
++
++	return res;
++
++}
++
++void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
++{
++	_adapter *padapter = pmlmeext->padapter;
++
++	if (!padapter)
++		return;
++
++	if (padapter->bDriverStopped == _TRUE)
++	{
++		_cancel_timer_ex(&pmlmeext->survey_timer);
++		_cancel_timer_ex(&pmlmeext->link_timer);
++		//_cancel_timer_ex(&pmlmeext->ADDBA_timer);
++	}
++}
++
++static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
++{	// if the channel is same, return 0. else return channel differential
++	uint len;
++	u8 channel;
++	u8 *p;
++	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
++	if (p)
++	{
++		channel = *(p + 2);
++		if(padapter->mlmeextpriv.cur_channel >= channel)
++		{
++			return (padapter->mlmeextpriv.cur_channel - channel);
++		}
++		else
++		{
++			return (channel-padapter->mlmeextpriv.cur_channel);
++		}
++	}
++	else
++	{
++		return 0;
++	}
++}
++
++static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
++{
++	u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++
++	  if(ptable->func)
++        {
++	 //receive the frames that ra(a1) is my address or ra(a1) is bc address.
++		if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
++			!_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
++		{
++			return;
++		}
++
++		ptable->func(padapter, precv_frame);
++        }
++
++}
++
++void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
++{
++	int index;
++	struct mlme_handler *ptable;
++#ifdef CONFIG_AP_MODE
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++#endif //CONFIG_AP_MODE
++	u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
++
++	RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
++		 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
++		  GetFrameType(pframe), GetFrameSubType(pframe)));
++
++#if 0
++	{
++		u8 *pbuf;
++		pbuf = GetAddr1Ptr(pframe);
++		DBG_871X("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
++		pbuf = GetAddr2Ptr(pframe);
++		DBG_871X("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
++		pbuf = GetAddr3Ptr(pframe);
++		DBG_871X("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf+1), *(pbuf+2), *(pbuf+3), *(pbuf+4), *(pbuf+5));
++	}
++#endif
++
++	if (GetFrameType(pframe) != WIFI_MGT_TYPE)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
++		return;
++	}
++
++	//receive the frames that ra(a1) is my address or ra(a1) is bc address.
++	if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) &&
++		!_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
++	{
++		return;
++	}
++
++	ptable = mlme_sta_tbl;
++
++	index = GetFrameSubType(pframe) >> 4;
++
++#ifdef CONFIG_TDLS
++	if((index << 4)==WIFI_ACTION){
++		//category==RTW_WLAN_CATEGORY_PUBLIC, action==TDLS_DISCOVERY_RESPONSE
++		if(*(pframe + IEEE80211_MGMT_HDR_LEN ) == RTW_WLAN_CATEGORY_PUBLIC
++			&& *(pframe + IEEE80211_MGMT_HDR_LEN + 1) == TDLS_DISCOVERY_RESPONSE )
++		{
++			DBG_871X("recv tdls discovery response frame\n");
++			On_TDLS_Dis_Rsp(padapter, precv_frame);
++		}
++	}
++#endif //CONFIG_TDLS
++
++	if (index > 13)
++	{
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
++		return;
++	}
++	ptable += index;
++
++#if 1
++	if (psta != NULL)
++	{
++		if (GetRetry(pframe))
++		{
++			if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
++			{
++				/* drop the duplicate management frame */
++				DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
++				return;
++			}
++		}
++		psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
++	}
++#else
++
++	if(GetRetry(pframe))
++	{
++		//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n"));
++		//return;
++	}
++#endif
++
++#ifdef CONFIG_AP_MODE
++	switch (GetFrameSubType(pframe))
++	{
++		case WIFI_AUTH:
++			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++				ptable->func = &OnAuth;
++			else
++				ptable->func = &OnAuthClient;
++			//pass through
++		case WIFI_ASSOCREQ:
++		case WIFI_REASSOCREQ:
++			_mgt_dispatcher(padapter, ptable, precv_frame);
++#ifdef CONFIG_HOSTAPD_MLME
++			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++				rtw_hostapd_mlme_rx(padapter, precv_frame);
++#endif
++			break;
++		case WIFI_PROBEREQ:
++			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++			{
++#ifdef CONFIG_HOSTAPD_MLME
++				rtw_hostapd_mlme_rx(padapter, precv_frame);
++#else
++				_mgt_dispatcher(padapter, ptable, precv_frame);
++#endif
++			}
++			else
++				_mgt_dispatcher(padapter, ptable, precv_frame);
++			break;
++		case WIFI_BEACON:
++			_mgt_dispatcher(padapter, ptable, precv_frame);
++			break;
++		case WIFI_ACTION:
++			//if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++			_mgt_dispatcher(padapter, ptable, precv_frame);
++			break;
++		default:
++			_mgt_dispatcher(padapter, ptable, precv_frame);
++			if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++				rtw_hostapd_mlme_rx(padapter, precv_frame);
++			break;
++	}
++#else
++
++	_mgt_dispatcher(padapter, ptable, precv_frame);
++
++#endif
++
++}
++
++#ifdef CONFIG_P2P
++u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
++{
++	bool response = _TRUE;
++
++#ifdef CONFIG_IOCTL_CFG80211
++	if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
++	{
++		if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
++			|| padapter->mlmepriv.wps_probe_resp_ie == NULL
++			|| padapter->mlmepriv.p2p_probe_resp_ie == NULL
++		)
++		{
++			DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
++				wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
++				padapter->mlmepriv.wps_probe_resp_ie,
++				padapter->mlmepriv.p2p_probe_resp_ie);
++			response = _FALSE;
++		}
++	}
++	else
++#endif //CONFIG_IOCTL_CFG80211
++	if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
++	{
++		//	do nothing if the device name is empty
++		if ( !padapter->wdinfo.device_name_len )
++		{
++			response	= _FALSE;
++		}
++	}
++
++	if (response == _TRUE)
++		issue_probersp_p2p( padapter, da);
++
++	return _SUCCESS;
++}
++#endif //CONFIG_P2P
++
++
++/****************************************************************************
++
++Following are the callback functions for each subtype of the management frames
++
++*****************************************************************************/
++
++unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
++{
++	unsigned int	ielen;
++	unsigned char	*p;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX 	*cur = &(pmlmeinfo->network);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint len = precv_frame->u.hdr.len;
++	u8 is_valid_p2p_probereq = _FALSE;
++
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++	struct rx_pkt_attrib	*pattrib = &precv_frame->u.hdr.attrib;
++	u8 wifi_test_chk_rate = 1;
++
++	if (	!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
++		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
++		!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
++		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
++		!rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
++	   )
++	{
++		//	Commented by Albert 2011/03/17
++		//	mcs_rate = 0 -> CCK 1M rate
++		//	mcs_rate = 1 -> CCK 2M rate
++		//	mcs_rate = 2 -> CCK 5.5M rate
++		//	mcs_rate = 3 -> CCK 11M rate
++		//	In the P2P mode, the driver should not support the CCK rate
++
++		//	Commented by Kurt 2012/10/16
++		//	IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client
++#ifdef CONFIG_WIFI_TEST
++		if ( pattrib->mcs_rate <= 3 )
++		{
++			wifi_test_chk_rate = 0;
++		}
++#endif //CONFIG_WIFI_TEST
++
++		if( wifi_test_chk_rate == 1 )
++		{
++			if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
++			{
++				if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
++				{
++					p2p_listen_state_process( padapter,  get_sa(pframe));
++
++					return _SUCCESS;
++				}
++
++				if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
++				{
++					goto _continue;
++				}
++			}
++		}
++	}
++
++_continue:
++#endif //CONFIG_P2P
++
++	if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
++	{
++		return _SUCCESS;
++	}
++
++	if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
++		check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
++	{
++		return _SUCCESS;
++	}
++
++
++	//DBG_871X("+OnProbeReq\n");
++
++#ifdef CONFIG_AUTO_AP_MODE
++	if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
++			pmlmepriv->cur_network.join_res == _TRUE)
++	{
++		_irqL	irqL;
++		struct sta_info	*psta;
++		u8 *mac_addr, *peer_addr;
++		struct sta_priv *pstapriv = &padapter->stapriv;
++		u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
++		//EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
++
++		p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
++			len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
++
++		if(!p || ielen !=14)
++			goto _non_rc_device;
++
++		if(!_rtw_memcmp(p+2, RC_OUI, sizeof(RC_OUI)))
++			goto _non_rc_device;
++
++		if(!_rtw_memcmp(p+6, get_sa(pframe), ETH_ALEN))
++		{
++			DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
++				MAC_ARG(get_sa(pframe)), MAC_ARG(p+6));
++
++			goto _non_rc_device;
++		}
++
++		DBG_871X("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__,  MAC_ARG(get_sa(pframe)));
++
++		//new a station
++		psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
++		if (psta == NULL)
++		{
++			// allocate a new one
++			DBG_871X("going to alloc stainfo for rc="MAC_FMT"\n",  MAC_ARG(get_sa(pframe)));
++			psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
++			if (psta == NULL)
++			{
++				//TODO:
++				DBG_871X(" Exceed the upper limit of supported clients...\n");
++				return _SUCCESS;
++			}
++
++			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++			if (rtw_is_list_empty(&psta->asoc_list))
++			{
++				psta->expire_to = pstapriv->expire_to;
++				rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
++				pstapriv->asoc_list_cnt++;
++			}
++			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++			//generate pairing ID
++			mac_addr = myid(&(padapter->eeprompriv));
++			peer_addr = psta->hwaddr;
++			psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5]));
++
++			//update peer stainfo
++			psta->isrc = _TRUE;
++			//psta->aid = 0;
++			//psta->mac_id = 2;
++
++			/* get a unique AID */
++			if (psta->aid > 0) {
++				DBG_871X("old AID %d\n", psta->aid);
++			} else {
++				for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
++					if (pstapriv->sta_aid[psta->aid - 1] == NULL)
++						break;
++
++				if (psta->aid > pstapriv->max_num_sta) {
++					psta->aid = 0;
++					DBG_871X("no room for more AIDs\n");
++					return _SUCCESS;
++				} else {
++					pstapriv->sta_aid[psta->aid - 1] = psta;
++					DBG_871X("allocate new AID = (%d)\n", psta->aid);
++				}
++			}
++
++			psta->qos_option = 1;
++			psta->htpriv.ht_option = _TRUE;
++			psta->ieee8021x_blocked = _FALSE;
++			psta->htpriv.ampdu_enable = _FALSE;
++			psta->htpriv.sgi = _FALSE;
++			psta->htpriv.bwmode = HT_CHANNEL_WIDTH_20;
++			psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++
++			//rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
++
++			psta->htpriv.agg_enable_bitmap = 0x0;//reset
++			psta->htpriv.candidate_tid_bitmap = 0x0;//reset
++
++			_rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
++
++			_enter_critical_bh(&psta->lock, &irqL);
++			psta->state |= _FW_LINKED;
++			_exit_critical_bh(&psta->lock, &irqL);
++
++			report_add_sta_event(padapter, psta->hwaddr, psta->aid);
++
++		}
++
++		issue_probersp(padapter, get_sa(pframe), _FALSE);
++
++		return _SUCCESS;
++
++	}
++
++_non_rc_device:
++
++	return _SUCCESS;
++#endif //CONFIG_AUTO_AP_MODE
++
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
++		check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
++	{
++		//don't process probe req
++		return _SUCCESS;
++	}
++#endif
++
++	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
++			len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
++
++
++	//check (wildcard) SSID
++	if (p != NULL)
++	{
++		if(is_valid_p2p_probereq == _TRUE)
++		{
++			goto _issue_probersp;
++		}
++
++		if ( (ielen != 0 && _FALSE ==_rtw_memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
++			|| (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
++		)
++		{
++			return _SUCCESS;
++		}
++
++_issue_probersp:
++
++		if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
++			pmlmepriv->cur_network.join_res == _TRUE)
++		{
++			//DBG_871X("+issue_probersp during ap mode\n");
++			issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
++		}
++
++	}
++
++	return _SUCCESS;
++
++}
++
++unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
++{
++	struct sta_info		*psta;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct sta_priv		*pstapriv = &padapter->stapriv;
++	u8	*pframe = precv_frame->u.hdr.rx_data;
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &padapter->wdinfo;
++#endif
++
++
++#ifdef CONFIG_P2P
++	if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
++	{
++		if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
++		{
++			if( _rtw_memcmp( pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
++			{
++				if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
++				{
++					pwdinfo->tx_prov_disc_info.benable = _FALSE;
++					issue_p2p_provision_request( padapter,
++												pwdinfo->tx_prov_disc_info.ssid.Ssid,
++												pwdinfo->tx_prov_disc_info.ssid.SsidLength,
++												pwdinfo->tx_prov_disc_info.peerDevAddr );
++				}
++				else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
++				{
++					pwdinfo->tx_prov_disc_info.benable = _FALSE;
++					issue_p2p_provision_request( padapter,
++												NULL,
++												0,
++												pwdinfo->tx_prov_disc_info.peerDevAddr );
++				}
++			}
++		}
++		return _SUCCESS;
++	}
++	else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
++	{
++		if ( _TRUE == pwdinfo->nego_req_info.benable )
++		{
++			DBG_871X( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
++			if( _rtw_memcmp( pwdinfo->nego_req_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
++			{
++				pwdinfo->nego_req_info.benable = _FALSE;
++				issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
++			}
++		}
++	}
++	else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
++	{
++		if ( _TRUE == pwdinfo->invitereq_info.benable )
++		{
++			DBG_871X( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
++			if( _rtw_memcmp( pwdinfo->invitereq_info.peer_macaddr, GetAddr2Ptr(pframe), ETH_ALEN ) )
++			{
++				pwdinfo->invitereq_info.benable = _FALSE;
++				issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
++			}
++		}
++	}
++#endif
++
++
++	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
++	{
++		report_survey_event(padapter, precv_frame);
++#ifdef CONFIG_CONCURRENT_MODE
++		report_survey_event(padapter->pbuddy_adapter, precv_frame);
++#endif
++#ifdef CONFIG_DUALMAC_CONCURRENT
++		dc_report_survey_event(padapter, precv_frame);
++#endif
++		return _SUCCESS;
++	}
++
++	#if 0 //move to validate_recv_mgnt_frame
++	if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
++	{
++		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
++		{
++			if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
++			{
++				psta->sta_stats.rx_mgnt_pkts++;
++			}
++		}
++	}
++	#endif
++
++	return _SUCCESS;
++
++}
++
++unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
++{
++	int cam_idx;
++	struct sta_info	*psta;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct sta_priv	*pstapriv = &padapter->stapriv;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint len = precv_frame->u.hdr.len;
++	u8 *p = NULL;
++	u32 ielen = 0;
++
++#ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
++	p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
++	if ((p != NULL) && (ielen > 0))
++	{
++		if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
++		{
++			/* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
++			DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
++			*(p + 1) = ielen - 1;
++		}
++	}
++#endif
++
++	if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
++	{
++		report_survey_event(padapter, precv_frame);
++#ifdef CONFIG_CONCURRENT_MODE
++		report_survey_event(padapter->pbuddy_adapter, precv_frame);
++#endif
++
++#ifdef CONFIG_DUALMAC_CONCURRENT
++		dc_report_survey_event(padapter, precv_frame);
++#endif
++
++		return _SUCCESS;
++	}
++
++	if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
++	{
++		if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
++		{
++			//check the vendor of the assoc AP
++			pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
++#ifdef CONFIG_P2P_PS
++			// do P2P PS Before link ? , ToDo
++			//process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
++#endif // CONFIG_P2P_PS
++
++			//update TSF Value
++			update_TSF(pmlmeext, pframe, len);
++
++			//start auth
++			start_clnt_auth(padapter);
++
++			return _SUCCESS;
++		}
++
++		if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
++		{
++			if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
++			{
++				#ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
++				//Merge from 8712 FW code
++				if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
++				{            // join wrong channel, deauth and reconnect
++					issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
++
++					report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL);
++					pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
++					return _SUCCESS;
++				}
++				#endif //CONFIG_PATCH_JOIN_WRONG_CHANNEL
++
++				//update WMM, ERP in the beacon
++				//todo: the timer is used instead of the number of the beacon received
++				if ((sta_rx_pkts(psta) & 0xf) == 0)
++				{
++					//DBG_871X("update_bcn_info\n");
++					update_beacon_info(padapter, pframe, len, psta);
++				}
++
++#ifdef CONFIG_DFS
++				process_csa_ie(padapter, pframe, len);	//channel switch announcement
++#endif //CONFIG_DFS
++
++#ifdef CONFIG_P2P_PS
++				//if(psta->ieee8021x_blocked == _FALSE) // do not allow P2P PS during EAPOL handshake ?
++				process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
++#endif //CONFIG_P2P_PS
++
++				#if 0 //move to validate_recv_mgnt_frame
++				psta->sta_stats.rx_mgnt_pkts++;
++				#endif
++			}
++		}
++		else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
++		{
++			if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
++			{
++				//update WMM, ERP in the beacon
++				//todo: the timer is used instead of the number of the beacon received
++				if ((sta_rx_pkts(psta) & 0xf) == 0)
++				{
++					//DBG_871X("update_bcn_info\n");
++					update_beacon_info(padapter, pframe, len, psta);
++				}
++
++				#if 0 //move to validate_recv_mgnt_frame
++				psta->sta_stats.rx_mgnt_pkts++;
++				#endif
++			}
++			else
++			{
++				//allocate a new CAM entry for IBSS station
++				if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
++				{
++					goto _END_ONBEACON_;
++				}
++
++				//get supported rate
++				if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL)
++				{
++					pmlmeinfo->FW_sta_info[cam_idx].status = 0;
++					goto _END_ONBEACON_;
++				}
++
++				//update TSF Value
++				update_TSF(pmlmeext, pframe, len);
++
++				//report sta add event
++				report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
++			}
++		}
++	}
++
++_END_ONBEACON_:
++
++	return _SUCCESS;
++
++}
++
++unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
++{
++#ifdef CONFIG_AP_MODE
++	_irqL irqL;
++	unsigned int	auth_mode, seq, ie_len;
++	unsigned char	*sa, *p;
++	u16	algorithm;
++	int	status;
++	static struct sta_info stat;
++	struct	sta_info	*pstat=NULL;
++	struct	sta_priv *pstapriv = &padapter->stapriv;
++	struct security_priv *psecuritypriv = &padapter->securitypriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint len = precv_frame->u.hdr.len;
++
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
++		check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
++	{
++		//don't process auth request;
++		return _SUCCESS;
++	}
++#endif //CONFIG_CONCURRENT_MODE
++
++	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
++		return _FAIL;
++
++	DBG_871X("+OnAuth\n");
++
++	sa = GetAddr2Ptr(pframe);
++
++	auth_mode = psecuritypriv->dot11AuthAlgrthm;
++	seq = cpu_to_le16(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + 2));
++	algorithm = cpu_to_le16(*(u16*)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN));
++
++	if (GetPrivacy(pframe))
++	{
++#if 0 //TODO: SW rtw_wep_decrypt
++		if (SWCRYPTO)
++		{
++			status = rtw_wep_decrypt(priv, pframe, pfrinfo->pktlen,
++				priv->pmib->dot1180211AuthEntry.dot11PrivacyAlgrthm);
++			if (status == FALSE)
++			{
++				SAVE_INT_AND_CLI(flags);
++				RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"wep-decrypt a Auth frame error!\n");
++				status = _STATS_CHALLENGE_FAIL_;
++				goto auth_fail;
++			}
++		}
++
++		seq = cpu_to_le16(*(unsigned short *)((unsigned int)pframe + WLAN_HDR_A3_LEN + 4 + 2));
++		algorithm = cpu_to_le16(*(unsigned short *)((unsigned int)pframe + WLAN_HDR_A3_LEN + 4));
++#endif
++	}
++
++
++	DBG_871X("auth alg=%x, seq=%X\n", algorithm, seq);
++
++	if (auth_mode == 2 &&
++			psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
++			psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
++		auth_mode = 0;
++
++	if ((algorithm > 0 && auth_mode == 0) ||	// rx a shared-key auth but shared not enabled
++		(algorithm == 0 && auth_mode == 1) )	// rx a open-system auth but shared-key is enabled
++	{
++		DBG_871X("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
++			algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
++
++		status = _STATS_NO_SUPP_ALG_;
++
++		goto auth_fail;
++	}
++
++#if 0 //ACL control
++	phead = &priv->wlan_acl_list;
++	plist = phead->next;
++	//check sa
++	if (acl_mode == 1)		// 1: positive check, only those on acl_list can be connected.
++		res = FAIL;
++	else
++		res = SUCCESS;
++
++	while(plist != phead)
++	{
++		paclnode = list_entry(plist, struct rtw_wlan_acl_node, list);
++		plist = plist->next;
++		if (!memcmp((void *)sa, paclnode->addr, 6)) {
++			if (paclnode->mode & 2) { // deny
++				res = FAIL;
++				break;
++			}
++			else {
++				res = SUCCESS;
++				break;
++			}
++		}
++	}
++
++	if (res != SUCCESS) {
++		RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"auth abort because ACL!\n");
++		return FAIL;
++	}
++#else
++	if(rtw_access_ctrl(padapter, sa) == _FALSE)
++	{
++		status = _STATS_UNABLE_HANDLE_STA_;
++		goto auth_fail;
++	}
++#endif
++
++	pstat = rtw_get_stainfo(pstapriv, sa);
++	if (pstat == NULL)
++	{
++		// allocate a new one
++		DBG_871X("going to alloc stainfo for sa="MAC_FMT"\n",  MAC_ARG(sa));
++		pstat = rtw_alloc_stainfo(pstapriv, sa);
++		if (pstat == NULL)
++		{
++			DBG_871X(" Exceed the upper limit of supported clients...\n");
++			status = _STATS_UNABLE_HANDLE_STA_;
++			goto auth_fail;
++		}
++
++		pstat->state = WIFI_FW_AUTH_NULL;
++		pstat->auth_seq = 0;
++
++		//pstat->flags = 0;
++		//pstat->capability = 0;
++	}
++	else
++	{
++		_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++		if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE)
++		{
++			rtw_list_delete(&pstat->asoc_list);
++			pstapriv->asoc_list_cnt--;
++			if (pstat->expire_to > 0)
++			{
++				//TODO: STA re_auth within expire_to
++			}
++		}
++		_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++		if (seq==1) {
++			//TODO: STA re_auth and auth timeout
++		}
++	}
++
++	_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
++	if (rtw_is_list_empty(&pstat->auth_list))
++	{
++		rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
++		pstapriv->auth_list_cnt++;
++	}
++	_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
++
++	if (pstat->auth_seq == 0)
++		pstat->expire_to = pstapriv->auth_to;
++
++	if ((pstat->auth_seq + 1) != seq)
++	{
++		DBG_871X("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
++			seq, pstat->auth_seq+1);
++		status = _STATS_OUT_OF_AUTH_SEQ_;
++		goto auth_fail;
++	}
++
++	if (algorithm==0 && (auth_mode == 0 || auth_mode == 2))
++	{
++		if (seq == 1)
++		{
++			pstat->state &= ~WIFI_FW_AUTH_NULL;
++			pstat->state |= WIFI_FW_AUTH_SUCCESS;
++			pstat->expire_to = pstapriv->assoc_to;
++			pstat->authalg = algorithm;
++		}
++		else
++		{
++			DBG_871X("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
++				seq, pstat->auth_seq+1);
++			status = _STATS_OUT_OF_AUTH_SEQ_;
++			goto auth_fail;
++		}
++	}
++	else // shared system or auto authentication
++	{
++		if (seq == 1)
++		{
++			//prepare for the challenging txt...
++
++			//get_random_bytes((void *)pstat->chg_txt, 128);//TODO:
++
++			pstat->state &= ~WIFI_FW_AUTH_NULL;
++			pstat->state |= WIFI_FW_AUTH_STATE;
++			pstat->authalg = algorithm;
++			pstat->auth_seq = 2;
++		}
++		else if (seq == 3)
++		{
++			//checking for challenging txt...
++			DBG_871X("checking for challenging txt...\n");
++
++			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
++					len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
++
++			if((p==NULL) || (ie_len<=0))
++			{
++				DBG_871X("auth rejected because challenge failure!(1)\n");
++				status = _STATS_CHALLENGE_FAIL_;
++				goto auth_fail;
++			}
++
++			if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128))
++			{
++				pstat->state &= (~WIFI_FW_AUTH_STATE);
++				pstat->state |= WIFI_FW_AUTH_SUCCESS;
++				// challenging txt is correct...
++				pstat->expire_to =  pstapriv->assoc_to;
++			}
++			else
++			{
++				DBG_871X("auth rejected because challenge failure!\n");
++				status = _STATS_CHALLENGE_FAIL_;
++				goto auth_fail;
++			}
++		}
++		else
++		{
++			DBG_871X("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
++				seq, pstat->auth_seq+1);
++			status = _STATS_OUT_OF_AUTH_SEQ_;
++			goto auth_fail;
++		}
++	}
++
++
++	// Now, we are going to issue_auth...
++	pstat->auth_seq = seq + 1;
++
++#ifdef CONFIG_NATIVEAP_MLME
++	issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
++#endif
++
++	if (pstat->state & WIFI_FW_AUTH_SUCCESS)
++		pstat->auth_seq = 0;
++
++
++	return _SUCCESS;
++
++auth_fail:
++
++	if(pstat)
++		rtw_free_stainfo(padapter , pstat);
++
++	pstat = &stat;
++	_rtw_memset((char *)pstat, '\0', sizeof(stat));
++	pstat->auth_seq = 2;
++	_rtw_memcpy(pstat->hwaddr, sa, 6);
++
++#ifdef CONFIG_NATIVEAP_MLME
++	issue_auth(padapter, pstat, (unsigned short)status);
++#endif
++
++#endif
++	return _FAIL;
++
++}
++
++unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
++{
++	unsigned int	seq, len, status, algthm, offset;
++	unsigned char	*p;
++	unsigned int	go2asoc = 0;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint pkt_len = precv_frame->u.hdr.len;
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	//check A1 matches or not
++	if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
++		return _SUCCESS;
++
++	if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
++		return _SUCCESS;
++
++	offset = (GetPrivacy(pframe))? 4: 0;
++
++	algthm 	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
++	seq 	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
++	status 	= le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
++
++	if (status != 0)
++	{
++		DBG_871X("clnt auth fail, status: %d\n", status);
++		if(status == 13)//&& pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto)
++		{
++			if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
++				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
++			else
++				pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
++			//pmlmeinfo->reauth_count = 0;
++		}
++
++		set_link_timer(pmlmeext, 1);
++		goto authclnt_fail;
++	}
++
++	if (seq == 2)
++	{
++		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
++		{
++			 // legendary shared system
++			p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
++				pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
++
++			if (p == NULL)
++			{
++				//DBG_871X("marc: no challenge text?\n");
++				goto authclnt_fail;
++			}
++
++			_rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
++			pmlmeinfo->auth_seq = 3;
++			issue_auth(padapter, NULL, 0);
++			set_link_timer(pmlmeext, REAUTH_TO);
++
++			return _SUCCESS;
++		}
++		else
++		{
++			// open system
++			go2asoc = 1;
++		}
++	}
++	else if (seq == 4)
++	{
++		if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
++		{
++			go2asoc = 1;
++		}
++		else
++		{
++			goto authclnt_fail;
++		}
++	}
++	else
++	{
++		// this is also illegal
++		//DBG_871X("marc: clnt auth failed due to illegal seq=%x\n", seq);
++		goto authclnt_fail;
++	}
++
++	if (go2asoc)
++	{
++		start_clnt_assoc(padapter);
++		return _SUCCESS;
++	}
++
++authclnt_fail:
++
++	//pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE);
++
++	return _FAIL;
++
++}
++
++unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
++{
++#ifdef CONFIG_AP_MODE
++	_irqL irqL;
++	u16 capab_info, listen_interval;
++	struct rtw_ieee802_11_elems elems;
++	struct sta_info	*pstat;
++	unsigned char		reassoc, *p, *pos, *wpa_ie;
++	unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
++	int		i, ie_len, wpa_ie_len, left;
++	unsigned char		supportRate[16];
++	int					supportRateNum;
++	unsigned short		status = _STATS_SUCCESSFUL_;
++	unsigned short		frame_type, ie_offset=0;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct security_priv *psecuritypriv = &padapter->securitypriv;
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX 	*cur = &(pmlmeinfo->network);
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint pkt_len = precv_frame->u.hdr.len;
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++	u8 p2p_status_code = P2P_STATUS_SUCCESS;
++	u8 *p2pie;
++	u32 p2pielen = 0;
++#ifdef CONFIG_WFD
++	u8	wfd_ie[ 128 ] = { 0x00 };
++	u32	wfd_ielen = 0;
++#endif // CONFIG_WFD
++#endif //CONFIG_P2P
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
++		check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
++	{
++		//don't process assoc request;
++		return _SUCCESS;
++	}
++#endif //CONFIG_CONCURRENT_MODE
++
++	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
++		return _FAIL;
++
++	frame_type = GetFrameSubType(pframe);
++	if (frame_type == WIFI_ASSOCREQ)
++	{
++		reassoc = 0;
++		ie_offset = _ASOCREQ_IE_OFFSET_;
++	}
++	else // WIFI_REASSOCREQ
++	{
++		reassoc = 1;
++		ie_offset = _REASOCREQ_IE_OFFSET_;
++	}
++
++
++	if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
++		DBG_871X("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
++		       "\n", reassoc, (unsigned long)pkt_len);
++		return _FAIL;
++	}
++
++	pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
++	if (pstat == (struct sta_info *)NULL)
++	{
++		status = _RSON_CLS2_;
++		goto asoc_class2_error;
++	}
++
++	capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
++	//capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
++	//listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2));
++	listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
++
++	left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
++	pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
++
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	// check if this stat has been successfully authenticated/assocated
++	if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
++	{
++		if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
++		{
++			status = _RSON_CLS2_;
++			goto asoc_class2_error;
++		}
++		else
++		{
++			pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
++			pstat->state |= WIFI_FW_ASSOC_STATE;
++		}
++	}
++	else
++	{
++		pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
++		pstat->state |= WIFI_FW_ASSOC_STATE;
++	}
++
++
++#if 0// todo:tkip_countermeasures
++	if (hapd->tkip_countermeasures) {
++		resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
++		goto fail;
++	}
++#endif
++
++	pstat->capability = capab_info;
++
++#if 0//todo:
++	//check listen_interval
++	if (listen_interval > hapd->conf->max_listen_interval) {
++		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
++			       HOSTAPD_LEVEL_DEBUG,
++			       "Too large Listen Interval (%d)",
++			       listen_interval);
++		resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
++		goto fail;
++	}
++
++	pstat->listen_interval = listen_interval;
++#endif
++
++	//now parse all ieee802_11 ie to point to elems
++	if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
++	    !elems.ssid) {
++		DBG_871X("STA " MAC_FMT " sent invalid association request\n",
++		       MAC_ARG(pstat->hwaddr));
++		status = _STATS_FAILURE_;
++		goto OnAssocReqFail;
++	}
++
++
++	// now we should check all the fields...
++	// checking SSID
++	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
++		pkt_len - WLAN_HDR_A3_LEN - ie_offset);
++	if (p == NULL)
++	{
++		status = _STATS_FAILURE_;
++	}
++
++	if (ie_len == 0) // broadcast ssid, however it is not allowed in assocreq
++		status = _STATS_FAILURE_;
++	else
++	{
++		// check if ssid match
++		if (!_rtw_memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
++			status = _STATS_FAILURE_;
++
++		if (ie_len != cur->Ssid.SsidLength)
++			status = _STATS_FAILURE_;
++	}
++
++	if(_STATS_SUCCESSFUL_ != status)
++		goto OnAssocReqFail;
++
++	// check if the supported rate is ok
++	p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
++	if (p == NULL) {
++		DBG_871X("Rx a sta assoc-req which supported rate is empty!\n");
++		// use our own rate set as statoin used
++		//_rtw_memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN);
++		//supportRateNum = AP_BSSRATE_LEN;
++
++		status = _STATS_FAILURE_;
++		goto OnAssocReqFail;
++	}
++	else {
++		_rtw_memcpy(supportRate, p+2, ie_len);
++		supportRateNum = ie_len;
++
++		p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
++				pkt_len - WLAN_HDR_A3_LEN - ie_offset);
++		if (p !=  NULL) {
++
++			if(supportRateNum<=sizeof(supportRate))
++			{
++				_rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
++				supportRateNum += ie_len;
++			}
++		}
++	}
++
++	//todo: mask supportRate between AP & STA -> move to update raid
++	//get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0);
++
++	//update station supportRate
++	pstat->bssratelen = supportRateNum;
++	_rtw_memcpy(pstat->bssrateset, supportRate, supportRateNum);
++
++
++	//check RSN/WPA/WPS
++	pstat->dot8021xalg = 0;
++	pstat->wpa_psk = 0;
++	pstat->wpa_group_cipher = 0;
++	pstat->wpa2_group_cipher = 0;
++	pstat->wpa_pairwise_cipher = 0;
++	pstat->wpa2_pairwise_cipher = 0;
++	_rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
++	if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
++
++		int group_cipher=0, pairwise_cipher=0;
++
++		wpa_ie = elems.rsn_ie;
++		wpa_ie_len = elems.rsn_ie_len;
++
++		if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
++		{
++			pstat->dot8021xalg = 1;//psk,  todo:802.1x
++			pstat->wpa_psk |= BIT(1);
++
++			pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
++			pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
++
++			if(!pstat->wpa2_group_cipher)
++				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
++
++			if(!pstat->wpa2_pairwise_cipher)
++				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
++		}
++		else
++		{
++			status = WLAN_STATUS_INVALID_IE;
++		}
++
++	} else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
++
++		int group_cipher=0, pairwise_cipher=0;
++
++		wpa_ie = elems.wpa_ie;
++		wpa_ie_len = elems.wpa_ie_len;
++
++		if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
++		{
++			pstat->dot8021xalg = 1;//psk,  todo:802.1x
++			pstat->wpa_psk |= BIT(0);
++
++			pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
++			pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
++
++			if(!pstat->wpa_group_cipher)
++				status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
++
++			if(!pstat->wpa_pairwise_cipher)
++				status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
++
++		}
++		else
++		{
++			status = WLAN_STATUS_INVALID_IE;
++		}
++
++	} else {
++		wpa_ie = NULL;
++		wpa_ie_len = 0;
++	}
++
++	if(_STATS_SUCCESSFUL_ != status)
++		goto OnAssocReqFail;
++
++	pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
++	//if (hapd->conf->wps_state && wpa_ie == NULL) { //todo: to check ap if supporting WPS
++	if(wpa_ie == NULL) {
++		if (elems.wps_ie) {
++			DBG_871X("STA included WPS IE in "
++				   "(Re)Association Request - assume WPS is "
++				   "used\n");
++			pstat->flags |= WLAN_STA_WPS;
++			//wpabuf_free(sta->wps_ie);
++			//sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
++			//				elems.wps_ie_len - 4);
++		} else {
++			DBG_871X("STA did not include WPA/RSN IE "
++				   "in (Re)Association Request - possible WPS "
++				   "use\n");
++			pstat->flags |= WLAN_STA_MAYBE_WPS;
++		}
++
++
++		// AP support WPA/RSN, and sta is going to do WPS, but AP is not ready
++		// that the selected registrar of AP is _FLASE
++		if((psecuritypriv->wpa_psk >0)
++			&& (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)))
++		{
++			if(pmlmepriv->wps_beacon_ie)
++			{
++				u8 selected_registrar = 0;
++
++				rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
++
++				if(!selected_registrar)
++				{
++					DBG_871X("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
++
++					status = _STATS_UNABLE_HANDLE_STA_;
++
++					goto OnAssocReqFail;
++				}
++			}
++		}
++
++	}
++	else
++	{
++		int copy_len;
++
++		if(psecuritypriv->wpa_psk == 0)
++		{
++			DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association "
++			"request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
++
++			status = WLAN_STATUS_INVALID_IE;
++
++			goto OnAssocReqFail;
++
++		}
++
++		if (elems.wps_ie) {
++			DBG_871X("STA included WPS IE in "
++				   "(Re)Association Request - WPS is "
++				   "used\n");
++			pstat->flags |= WLAN_STA_WPS;
++			copy_len=0;
++		}
++		else
++		{
++			copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
++		}
++
++
++		if(copy_len>0)
++			_rtw_memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
++
++	}
++
++
++	// check if there is WMM IE & support WWM-PS
++	pstat->flags &= ~WLAN_STA_WME;
++	pstat->qos_option = 0;
++	pstat->qos_info = 0;
++	pstat->has_legacy_ac = _TRUE;
++	pstat->uapsd_vo = 0;
++	pstat->uapsd_vi = 0;
++	pstat->uapsd_be = 0;
++	pstat->uapsd_bk = 0;
++	if (pmlmepriv->qospriv.qos_option)
++	{
++		p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
++		for (;;)
++		{
++			p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
++			if (p != NULL) {
++				if (_rtw_memcmp(p+2, WMM_IE, 6)) {
++
++					pstat->flags |= WLAN_STA_WME;
++
++					pstat->qos_option = 1;
++					pstat->qos_info = *(p+8);
++
++					pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
++
++					if((pstat->qos_info&0xf) !=0xf)
++						pstat->has_legacy_ac = _TRUE;
++					else
++						pstat->has_legacy_ac = _FALSE;
++
++					if(pstat->qos_info&0xf)
++					{
++						if(pstat->qos_info&BIT(0))
++							pstat->uapsd_vo = BIT(0)|BIT(1);
++						else
++							pstat->uapsd_vo = 0;
++
++						if(pstat->qos_info&BIT(1))
++							pstat->uapsd_vi = BIT(0)|BIT(1);
++						else
++							pstat->uapsd_vi = 0;
++
++						if(pstat->qos_info&BIT(2))
++							pstat->uapsd_bk = BIT(0)|BIT(1);
++						else
++							pstat->uapsd_bk = 0;
++
++						if(pstat->qos_info&BIT(3))
++							pstat->uapsd_be = BIT(0)|BIT(1);
++						else
++							pstat->uapsd_be = 0;
++
++					}
++
++					break;
++				}
++			}
++			else {
++				break;
++			}
++			p = p + ie_len + 2;
++		}
++	}
++
++
++#ifdef CONFIG_80211N_HT
++	/* save HT capabilities in the sta object */
++	_rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
++	if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
++	{
++		pstat->flags |= WLAN_STA_HT;
++
++		pstat->flags |= WLAN_STA_WME;
++
++		_rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
++
++	} else
++		pstat->flags &= ~WLAN_STA_HT;
++
++
++	if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
++	{
++		status = _STATS_FAILURE_;
++		goto OnAssocReqFail;
++	}
++
++
++	if ((pstat->flags & WLAN_STA_HT) &&
++		    ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
++		      (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
++	{
++		DBG_871X("HT: " MAC_FMT " tried to "
++				   "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
++
++		//status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
++		//goto OnAssocReqFail;
++	}
++#endif /* CONFIG_80211N_HT */
++
++       //
++       //if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)//?
++	pstat->flags |= WLAN_STA_NONERP;
++	for (i = 0; i < pstat->bssratelen; i++) {
++		if ((pstat->bssrateset[i] & 0x7f) > 22) {
++			pstat->flags &= ~WLAN_STA_NONERP;
++			break;
++		}
++	}
++
++	if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
++		pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
++	else
++		pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
++
++
++
++	if (status != _STATS_SUCCESSFUL_)
++		goto OnAssocReqFail;
++
++#ifdef CONFIG_P2P
++	pstat->is_p2p_device = _FALSE;
++	if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
++	{
++		if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
++		{
++			pstat->is_p2p_device = _TRUE;
++			if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
++			{
++				pstat->p2p_status_code = p2p_status_code;
++				status = _STATS_CAP_FAIL_;
++				goto OnAssocReqFail;
++			}
++		}
++#ifdef CONFIG_WFD
++		if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
++		{
++			u8	attr_content[ 10 ] = { 0x00 };
++			u32	attr_contentlen = 0;
++
++			DBG_8192C( "[%s] WFD IE Found!!\n", __FUNCTION__ );
++			rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
++			if ( attr_contentlen )
++			{
++				pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
++				DBG_8192C( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
++			}
++		}
++#endif
++	}
++	pstat->p2p_status_code = p2p_status_code;
++#endif //CONFIG_P2P
++
++	//TODO: identify_proprietary_vendor_ie();
++	// Realtek proprietary IE
++	// identify if this is Broadcom sta
++	// identify if this is ralink sta
++	// Customer proprietary IE
++
++
++
++	/* get a unique AID */
++	if (pstat->aid > 0) {
++		DBG_871X("  old AID %d\n", pstat->aid);
++	} else {
++		for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
++			if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
++				break;
++
++		//if (pstat->aid > NUM_STA) {
++		if (pstat->aid > pstapriv->max_num_sta) {
++
++			pstat->aid = 0;
++
++			DBG_871X("  no room for more AIDs\n");
++
++			status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
++
++			goto OnAssocReqFail;
++
++
++		} else {
++			pstapriv->sta_aid[pstat->aid - 1] = pstat;
++			DBG_871X("allocate new AID = (%d)\n", pstat->aid);
++		}
++	}
++
++
++	pstat->state &= (~WIFI_FW_ASSOC_STATE);
++	pstat->state |= WIFI_FW_ASSOC_SUCCESS;
++
++	_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
++	if (!rtw_is_list_empty(&pstat->auth_list))
++	{
++		rtw_list_delete(&pstat->auth_list);
++		pstapriv->auth_list_cnt--;
++	}
++	_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
++
++	_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++	if (rtw_is_list_empty(&pstat->asoc_list))
++	{
++		pstat->expire_to = pstapriv->expire_to;
++		rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
++		pstapriv->asoc_list_cnt++;
++	}
++	_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++	// now the station is qualified to join our BSS...
++	if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
++	{
++#ifdef CONFIG_NATIVEAP_MLME
++		//.1 bss_cap_update & sta_info_update
++		bss_cap_update_on_sta_join(padapter, pstat);
++		sta_info_update(padapter, pstat);
++
++		//issue assoc rsp before notify station join event.
++		if (frame_type == WIFI_ASSOCREQ)
++			issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
++		else
++			issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
++
++		//.2 - report to upper layer
++		DBG_871X("indicate_sta_join_event to upper layer - hostapd\n");
++
++#ifdef CONFIG_IOCTL_CFG80211
++		#ifdef COMPAT_KERNEL_RELEASE
++		rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
++		#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++		rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
++		#else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++		_enter_critical_bh(&pstat->lock, &irqL);
++		if(pstat->passoc_req)
++		{
++			rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
++			pstat->passoc_req = NULL;
++			pstat->assoc_req_len = 0;
++		}
++
++		pstat->passoc_req =  rtw_zmalloc(pkt_len);
++		if(pstat->passoc_req)
++		{
++			_rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
++			pstat->assoc_req_len = pkt_len;
++		}
++		_exit_critical_bh(&pstat->lock, &irqL);
++		#endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
++#else
++		rtw_indicate_sta_assoc_event(padapter, pstat);
++#endif //CONFIG_IOCTL_CFG80211
++
++		//.3-(1) report sta add event
++		report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
++
++/*
++		//issue assoc rsp before notify station join event.
++		if (frame_type == WIFI_ASSOCREQ)
++			issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
++		else
++			issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
++*/
++
++#endif
++	}
++
++	return _SUCCESS;
++
++asoc_class2_error:
++
++#ifdef CONFIG_NATIVEAP_MLME
++	issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
++#endif
++
++	return _FAIL;
++
++OnAssocReqFail:
++
++
++#ifdef CONFIG_NATIVEAP_MLME
++	pstat->aid = 0;
++	if (frame_type == WIFI_ASSOCREQ)
++		issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
++	else
++		issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
++#endif
++
++
++#endif /* CONFIG_AP_MODE */
++
++	return _FAIL;
++
++}
++
++unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
++{
++	uint i;
++	int res;
++	unsigned short	status;
++	PNDIS_802_11_VARIABLE_IEs	pIE;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	//WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint pkt_len = precv_frame->u.hdr.len;
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	//check A1 matches or not
++	if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
++		return _SUCCESS;
++
++	if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
++		return _SUCCESS;
++
++	if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
++		return _SUCCESS;
++
++	_cancel_timer_ex(&pmlmeext->link_timer);
++
++	//status
++	if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
++	{
++		DBG_871X("assoc reject, status code: %d\n", status);
++		pmlmeinfo->state = WIFI_FW_NULL_STATE;
++		res = -4;
++		goto report_assoc_result;
++	}
++
++	//get capabilities
++	pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
++
++	//set slot time
++	pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
++
++	//AID
++	res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
++
++	//following are moved to join event callback function
++	//to handle HT, WMM, rate adaptive, update MAC reg
++	//for not to handle the synchronous IO in the tasklet
++	for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
++	{
++		pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
++
++		switch (pIE->ElementID)
++		{
++			case _VENDOR_SPECIFIC_IE_:
++				if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6))	//WMM
++				{
++					WMM_param_handler(padapter, pIE);
++				}
++#if defined(CONFIG_P2P) && defined(CONFIG_WFD)
++				else if ( _rtw_memcmp(pIE->data, WFD_OUI, 4))		//WFD
++				{
++					DBG_871X( "[%s] Found WFD IE\n", __FUNCTION__ );
++					WFD_info_handler( padapter, pIE );
++				}
++#endif
++				break;
++
++			case _HT_CAPABILITY_IE_:	//HT caps
++				HT_caps_handler(padapter, pIE);
++				break;
++
++			case _HT_EXTRA_INFO_IE_:	//HT info
++				HT_info_handler(padapter, pIE);
++				break;
++
++			case _ERPINFO_IE_:
++				ERP_IE_handler(padapter, pIE);
++
++			default:
++				break;
++		}
++
++		i += (pIE->Length + 2);
++	}
++
++	pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
++	pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
++
++	//Update Basic Rate Table for spec, 2010-12-28 , by thomas
++	UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
++
++#ifdef CONFIG_IOCTL_CFG80211
++	if (!rtw_cfg80211_check_bss(padapter)) {
++		DBG_871X("rtw_cfg80211_check_bss() : BSS not found !!\n");
++		res = -2;
++		goto report_assoc_result;
++	}
++#endif
++
++report_assoc_result:
++	if (res > 0) {
++		rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
++	} else {
++		rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
++	}
++
++	report_join_res(padapter, res);
++	return _SUCCESS;
++}
++
++unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
++{
++	unsigned short	reason;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++#ifdef CONFIG_P2P
++	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
++#endif //CONFIG_P2P
++
++	//check A3
++	if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
++		return _SUCCESS;
++
++#ifdef CONFIG_P2P
++	if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
++	{
++		_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
++		_set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
++	}
++#endif //CONFIG_P2P
++
++	reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
++
++	DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason);
++
++#ifdef CONFIG_AP_MODE
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++	{
++		_irqL irqL;
++		struct sta_info *psta;
++		struct sta_priv *pstapriv = &padapter->stapriv;
++
++		//_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++		//rtw_free_stainfo(padapter, psta);
++		//_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++		DBG_871X("%s, STA:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(GetAddr2Ptr(pframe)));
++
++		psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
++		if(psta)
++		{
++			u8 updated;
++
++			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++			if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
++			{
++				rtw_list_delete(&psta->asoc_list);
++				pstapriv->asoc_list_cnt--;
++				updated = ap_free_sta(padapter, psta, _FALSE, reason);
++
++			}
++			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++			associated_clients_update(padapter, updated);
++		}
++
++
++		return _SUCCESS;
++	}
++	else
++#endif
++	{
++		int	ignore_received_deauth = 0;
++
++		//	Commented by Albert 20130604
++		//	Before sending the auth frame to start the STA/GC mode connection with AP/GO,
++		//	we will send the deauth first.
++		//	However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth.
++		//	Added the following code to avoid this case.
++		if ( ( pmlmeinfo->state & WIFI_FW_AUTH_STATE ) ||
++			( pmlmeinfo->state & WIFI_FW_ASSOC_STATE ) )
++		{
++			if ( reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA )
++			{
++				ignore_received_deauth = 1;
++			} else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
++				// TODO: 802.11r
++				ignore_received_deauth = 1;
++			}
++		}
++
++		DBG_871X("%s, STA:" MAC_FMT ", ignore = %d\n", __FUNCTION__, MAC_ARG(GetAddr3Ptr(pframe)), ignore_received_deauth);
++		if ( 0 == ignore_received_deauth )
++		{
++			receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
++		}
++	}
++	pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
++	return _SUCCESS;
++
++}
++
++unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
++{
++	unsigned short	reason;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++#ifdef CONFIG_P2P
++	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
++#endif //CONFIG_P2P
++
++	//check A3
++	if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
++		return _SUCCESS;
++
++#ifdef CONFIG_P2P
++	if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
++	{
++		_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
++		_set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
++	}
++#endif //CONFIG_P2P
++
++	reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
++
++        DBG_871X("%s Reason code(%d)\n", __FUNCTION__,reason);
++
++#ifdef CONFIG_AP_MODE
++	if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
++	{
++		_irqL irqL;
++		struct sta_info *psta;
++		struct sta_priv *pstapriv = &padapter->stapriv;
++
++		//_enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++		//rtw_free_stainfo(padapter, psta);
++		//_exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
++
++		DBG_871X("%s, STA:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(GetAddr2Ptr(pframe)));
++
++		psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
++		if(psta)
++		{
++			u8 updated;
++
++			_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++			if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
++			{
++				rtw_list_delete(&psta->asoc_list);
++				pstapriv->asoc_list_cnt--;
++				updated = ap_free_sta(padapter, psta, _FALSE, reason);
++
++			}
++			_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
++
++			associated_clients_update(padapter, updated);
++		}
++
++		return _SUCCESS;
++	}
++	else
++#endif
++	{
++		DBG_871X("%s, STA:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(GetAddr3Ptr(pframe)));
++
++		receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
++	}
++	pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
++	return _SUCCESS;
++
++}
++
++unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
++{
++	DBG_871X("%s\n", __FUNCTION__);
++	return _SUCCESS;
++}
++
++unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
++{
++	unsigned int ret = _FAIL;
++	struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(mlmeext->mlmext_info);
++
++	if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
++		ret = _SUCCESS;
++		goto exit;
++	}
++
++	if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
++
++		int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
++		int ch_offset = -1;
++		u8 bwmode;
++		struct ieee80211_info_element *ie;
++
++		DBG_871X(FUNC_NDEV_FMT" from "MAC_FMT"\n",
++			FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
++
++		for_each_ie(ie, ies, ies_len) {
++			if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
++				ch_switch_mode = ie->data[0];
++				ch = ie->data[1];
++				ch_switch_cnt = ie->data[2];
++				DBG_871X("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
++					ch_switch_mode, ch, ch_switch_cnt);
++			}
++			else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
++				ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
++				DBG_871X("ch_offset:%d\n", ch_offset);
++			}
++		}
++
++		if (ch == -1)
++			return _SUCCESS;
++
++		if (ch_offset == -1)
++			bwmode = mlmeext->cur_bwmode;
++		else
++			bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
++				HT_CHANNEL_WIDTH_20 : HT_CHANNEL_WIDTH_40;
++
++		ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
++
++		/* todo:
++		 * 1. the decision of channel switching
++		 * 2. things after channel switching
++		 */
++
++		ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
++	}
++
++exit:
++	return ret;
++}
++
++unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
++{
++	unsigned int ret = _FAIL;
++	struct sta_info *psta = NULL;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint frame_len = precv_frame->u.hdr.len;
++	u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
++	u8 category;
++	u8 action;
++
++	DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
++
++	psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
++
++	if (!psta)
++		goto exit;
++
++	category = frame_body[0];
++	if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
++		goto exit;
++
++	action = frame_body[1];
++	switch (action) {
++	case RTW_WLAN_ACTION_SPCT_MSR_REQ:
++	case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
++	case RTW_WLAN_ACTION_SPCT_TPC_REQ:
++	case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
++		break;
++	case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
++		#ifdef CONFIG_SPCT_CH_SWITCH
++		ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
++			frame_len-(frame_body-pframe)-2);
++		#endif
++		break;
++	default:
++		break;
++	}
++
++exit:
++	return ret;
++}
++
++unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
++{
++	return _SUCCESS;
++}
++
++unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
++{
++	return _SUCCESS;
++}
++
++unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
++{
++	u8 *addr;
++	struct sta_info *psta=NULL;
++	struct recv_reorder_ctrl *preorder_ctrl;
++	unsigned char		*frame_body;
++	unsigned char		category, action;
++	unsigned short	tid, status, reason_code = 0;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++
++	//check RA matches or not
++	if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode
++		return _SUCCESS;
++
++/*
++	//check A1 matches or not
++	if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
++		return _SUCCESS;
++*/
++	DBG_871X("%s\n", __FUNCTION__);
++
++	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
++		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
++			return _SUCCESS;
++
++	addr = GetAddr2Ptr(pframe);
++	psta = rtw_get_stainfo(pstapriv, addr);
++
++	if(psta==NULL)
++		return _SUCCESS;
++
++	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
++
++	category = frame_body[0];
++	if (category == RTW_WLAN_CATEGORY_BACK)// representing Block Ack
++	{
++#ifdef CONFIG_TDLS
++		if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
++			(psta->htpriv.ht_option==_TRUE) &&
++			(psta->htpriv.ampdu_enable==_TRUE) )
++		{
++			//do nothing; just don't want to return _SUCCESS;
++		}
++		else
++#endif //CONFIG_TDLS
++		if (!pmlmeinfo->HT_enable)
++		{
++			return _SUCCESS;
++		}
++
++		action = frame_body[1];
++		DBG_871X("%s, action=%d\n", __FUNCTION__, action);
++		switch (action)
++		{
++			case RTW_WLAN_ACTION_ADDBA_REQ: //ADDBA request
++
++				_rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
++				//process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe));
++				process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
++
++				if(pmlmeinfo->bAcceptAddbaReq == _TRUE)
++				{
++					issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
++				}
++				else
++				{
++					issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);//reject ADDBA Req
++				}
++
++				break;
++
++			case RTW_WLAN_ACTION_ADDBA_RESP: //ADDBA response
++
++				//status = frame_body[3] | (frame_body[4] << 8); //endian issue
++				status = RTW_GET_LE16(&frame_body[3]);
++				tid = ((frame_body[5] >> 2) & 0x7);
++
++				if (status == 0)
++				{	//successful
++					DBG_871X("agg_enable for TID=%d\n", tid);
++					psta->htpriv.agg_enable_bitmap |= 1 << tid;
++					psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
++				}
++				else
++				{
++					psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
++				}
++
++				//DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap);
++				break;
++
++			case RTW_WLAN_ACTION_DELBA: //DELBA
++				if ((frame_body[3] & BIT(3)) == 0)
++				{
++					psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
++					psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
++
++					//reason_code = frame_body[4] | (frame_body[5] << 8);
++					reason_code = RTW_GET_LE16(&frame_body[4]);
++				}
++				else if((frame_body[3] & BIT(3)) == BIT(3))
++				{
++					tid = (frame_body[3] >> 4) & 0x0F;
++
++					preorder_ctrl =  &psta->recvreorder_ctrl[tid];
++					preorder_ctrl->enable = _FALSE;
++					preorder_ctrl->indicate_seq = 0xffff;
++					#ifdef DBG_RX_SEQ
++					DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
++						preorder_ctrl->indicate_seq);
++					#endif
++				}
++
++				DBG_871X("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
++				//todo: how to notify the host while receiving DELETE BA
++				break;
++
++			default:
++				break;
++		}
++	}
++
++	return _SUCCESS;
++}
++
++#ifdef CONFIG_P2P
++
++static int get_reg_classes_full_count(struct p2p_channels channel_list) {
++	int cnt = 0;
++	int i;
++
++	for (i = 0; i < channel_list.reg_classes; i++) {
++		cnt += channel_list.reg_class[i].channels;
++	}
++
++	return cnt;
++}
++
++static void get_channel_cnt_24g_5gl_5gh(  struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
++{
++	int	i = 0;
++
++	*p24g_cnt = 0;
++	*p5gl_cnt = 0;
++	*p5gh_cnt = 0;
++
++	for( i = 0; i < pmlmeext->max_chan_nums; i++ )
++	{
++		if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
++		{
++			(*p24g_cnt)++;
++		}
++		else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
++		{
++			//	Just include the channel 36, 40, 44, 48 channels for 5G low
++			(*p5gl_cnt)++;
++		}
++		else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
++		{
++			//	Just include the channel 149, 153, 157, 161 channels for 5G high
++			(*p5gh_cnt)++;
++		}
++	}
++}
++
++void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
++{
++
++	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
++	u8			action = P2P_PUB_ACTION_ACTION;
++	u32			p2poui = cpu_to_be32(P2POUI);
++	u8			oui_subtype = P2P_GO_NEGO_REQ;
++	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
++	u8			wpsielen = 0, p2pielen = 0, i;
++	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
++	u16			len_channellist_attr = 0;
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
++
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	DBG_871X( "[%s] In\n", __FUNCTION__ );
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
++	pwdinfo->negotiation_dialog_token = 1;	//	Initialize the dialog value
++	pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
++
++
++
++	//	WPS Section
++	wpsielen = 0;
++	//	WPS OUI
++	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
++	wpsielen += 4;
++
++	//	WPS version
++	//	Type:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
++	wpsielen += 2;
++
++	//	Length:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++	wpsielen += 2;
++
++	//	Value:
++	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
++
++	//	Device Password ID
++	//	Type:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
++	wpsielen += 2;
++
++	//	Length:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
++	wpsielen += 2;
++
++	//	Value:
++
++	if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
++	{
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
++	}
++	else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
++	{
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
++	}
++	else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
++	{
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
++	}
++
++	wpsielen += 2;
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
++
++
++	//	P2P IE Section.
++
++	//	P2P OUI
++	p2pielen = 0;
++	p2pie[ p2pielen++ ] = 0x50;
++	p2pie[ p2pielen++ ] = 0x6F;
++	p2pie[ p2pielen++ ] = 0x9A;
++	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++	//	Commented by Albert 20110306
++	//	According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes
++	//	1. P2P Capability
++	//	2. Group Owner Intent
++	//	3. Configuration Timeout
++	//	4. Listen Channel
++	//	5. Extended Listen Timing
++	//	6. Intended P2P Interface Address
++	//	7. Channel List
++	//	8. P2P Device Info
++	//	9. Operating Channel
++
++
++	//	P2P Capability
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Device Capability Bitmap, 1 byte
++	p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
++
++	//	Group Capability Bitmap, 1 byte
++	if ( pwdinfo->persistent_supported )
++	{
++		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
++	}
++	else
++	{
++		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
++	}
++
++
++	//	Group Owner Intent
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Todo the tie breaker bit.
++	p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
++
++	//	Configuration Timeout
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
++
++
++	//	Listen Channel
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Operating Class
++	p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
++
++	//	Channel Number
++	p2pie[ p2pielen++ ] = pwdinfo->listen_channel;	//	listening channel number
++
++
++	//	Extended Listen Timing ATTR
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Availability Period
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
++	p2pielen += 2;
++
++	//	Availability Interval
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
++	p2pielen += 2;
++
++
++	//	Intended P2P Interface Address
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
++	p2pielen += 2;
++
++	//	Value:
++	_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++	p2pielen += ETH_ALEN;
++
++
++	//	Channel List
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
++
++	// Length:
++	// Country String(3)
++	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
++	// + number of channels in all classes
++	len_channellist_attr = 3
++	   + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
++	   + get_reg_classes_full_count(pmlmeext->channel_list);
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++	{
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
++	}
++	else
++	{
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++	}
++#else
++
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++
++#endif
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Channel Entry List
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++	{
++		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++
++		//	Operating Class
++		if ( pbuddy_mlmeext->cur_channel > 14 )
++		{
++			if ( pbuddy_mlmeext->cur_channel >= 149 )
++			{
++				p2pie[ p2pielen++ ] = 0x7c;
++			}
++			else
++			{
++				p2pie[ p2pielen++ ] = 0x73;
++			}
++		}
++		else
++		{
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++
++		//	Number of Channels
++		//	Just support 1 channel and this channel is AP's channel
++		p2pie[ p2pielen++ ] = 1;
++
++		//	Channel List
++		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
++	}
++	else
++	{
++		int i,j;
++		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++			//	Operating Class
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++			//	Number of Channels
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++			//	Channel List
++			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++			}
++		}
++	}
++#else // CONFIG_CONCURRENT_MODE
++	{
++		int i,j;
++		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++			//	Operating Class
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++			//	Number of Channels
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++			//	Channel List
++			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++			}
++		}
++	}
++#endif // CONFIG_CONCURRENT_MODE
++
++	//	Device Info
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
++
++	//	Length:
++	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
++	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
++	p2pielen += 2;
++
++	//	Value:
++	//	P2P Device Address
++	_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++	p2pielen += ETH_ALEN;
++
++	//	Config Method
++	//	This field should be big endian. Noted by P2P specification.
++
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
++
++	p2pielen += 2;
++
++	//	Primary Device Type
++	//	Category ID
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
++	p2pielen += 2;
++
++	//	OUI
++	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
++	p2pielen += 4;
++
++	//	Sub Category ID
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
++	p2pielen += 2;
++
++	//	Number of Secondary Device Types
++	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
++
++	//	Device Name
++	//	Type:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++	p2pielen += 2;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
++	p2pielen += 2;
++
++	//	Value:
++	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
++	p2pielen += pwdinfo->device_name_len;
++
++
++	//	Operating Channel
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Operating Class
++	if ( pwdinfo->operating_channel <= 14 )
++	{
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x51;
++	}
++	else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
++	{
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x73;
++	}
++	else
++	{
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x7c;
++	}
++
++	//	Channel Number
++	p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++#ifdef CONFIG_WFD
++	wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
++	pframe += wfdielen;
++	pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++
++void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
++{
++
++	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
++	u8			action = P2P_PUB_ACTION_ACTION;
++	u32			p2poui = cpu_to_be32(P2POUI);
++	u8			oui_subtype = P2P_GO_NEGO_RESP;
++	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
++	u8			p2pielen = 0, i;
++	uint			wpsielen = 0;
++	u16			wps_devicepassword_id = 0x0000;
++	uint			wps_devicepassword_id_len = 0;
++	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
++	u16			len_channellist_attr = 0;
++
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
++
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	DBG_871X( "[%s] In, result = %d\n", __FUNCTION__,  result );
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
++	pwdinfo->negotiation_dialog_token = frame_body[7];	//	The Dialog Token of provisioning discovery request frame.
++	pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
++
++	//	Commented by Albert 20110328
++	//	Try to get the device password ID from the WPS IE of group negotiation request frame
++	//	WiFi Direct test plan 5.1.15
++	rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
++	rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
++	wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
++
++	_rtw_memset( wpsie, 0x00, 255 );
++	wpsielen = 0;
++
++	//	WPS Section
++	wpsielen = 0;
++	//	WPS OUI
++	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
++	wpsielen += 4;
++
++	//	WPS version
++	//	Type:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
++	wpsielen += 2;
++
++	//	Length:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++	wpsielen += 2;
++
++	//	Value:
++	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
++
++	//	Device Password ID
++	//	Type:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
++	wpsielen += 2;
++
++	//	Length:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
++	wpsielen += 2;
++
++	//	Value:
++	if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
++	{
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
++	}
++	else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
++	{
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
++	}
++	else
++	{
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
++	}
++	wpsielen += 2;
++
++	//	Commented by Kurt 20120113
++	//	If some device wants to do p2p handshake without sending prov_disc_req
++	//	We have to get peer_req_cm from here.
++	if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
++	{
++		if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
++		{
++			_rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
++		}
++		else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
++		{
++			_rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
++		}
++		else
++		{
++			_rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
++		}
++	}
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
++
++
++	//	P2P IE Section.
++
++	//	P2P OUI
++	p2pielen = 0;
++	p2pie[ p2pielen++ ] = 0x50;
++	p2pie[ p2pielen++ ] = 0x6F;
++	p2pie[ p2pielen++ ] = 0x9A;
++	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++	//	Commented by Albert 20100908
++	//	According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes
++	//	1. Status
++	//	2. P2P Capability
++	//	3. Group Owner Intent
++	//	4. Configuration Timeout
++	//	5. Operating Channel
++	//	6. Intended P2P Interface Address
++	//	7. Channel List
++	//	8. Device Info
++	//	9. Group ID	( Only GO )
++
++
++	//	ToDo:
++
++	//	P2P Status
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = result;
++
++	//	P2P Capability
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Device Capability Bitmap, 1 byte
++
++	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
++	{
++		//	Commented by Albert 2011/03/08
++		//	According to the P2P specification
++		//	if the sending device will be client, the P2P Capability should be reserved of group negotation response frame
++		p2pie[ p2pielen++ ] = 0;
++	}
++	else
++	{
++		//	Be group owner or meet the error case
++		p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
++	}
++
++	//	Group Capability Bitmap, 1 byte
++	if ( pwdinfo->persistent_supported )
++	{
++		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
++	}
++	else
++	{
++		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
++	}
++
++	//	Group Owner Intent
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
++	p2pielen += 2;
++
++	//	Value:
++	if ( pwdinfo->peer_intent & 0x01 )
++	{
++		//	Peer's tie breaker bit is 1, our tie breaker bit should be 0
++		p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
++	}
++	else
++	{
++		//	Peer's tie breaker bit is 0, our tie breaker bit should be 1
++		p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
++	}
++
++
++	//	Configuration Timeout
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
++
++	//	Operating Channel
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Operating Class
++	if ( pwdinfo->operating_channel <= 14 )
++	{
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x51;
++	}
++	else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
++	{
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x73;
++	}
++	else
++	{
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x7c;
++	}
++
++	//	Channel Number
++	p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
++
++	//	Intended P2P Interface Address
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
++	p2pielen += 2;
++
++	//	Value:
++	_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++	p2pielen += ETH_ALEN;
++
++	//	Channel List
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
++
++	// Country String(3)
++	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
++	// + number of channels in all classes
++	len_channellist_attr = 3
++	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
++	   + get_reg_classes_full_count(pmlmeext->channel_list);
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++	{
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
++	}
++	else
++	{
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++	}
++#else
++
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++
++ #endif
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Channel Entry List
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++	{
++		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++
++		//	Operating Class
++		if ( pbuddy_mlmeext->cur_channel > 14 )
++		{
++			if ( pbuddy_mlmeext->cur_channel >= 149 )
++			{
++				p2pie[ p2pielen++ ] = 0x7c;
++			}
++			else
++			{
++				p2pie[ p2pielen++ ] = 0x73;
++			}
++		}
++		else
++		{
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++
++		//	Number of Channels
++		//	Just support 1 channel and this channel is AP's channel
++		p2pie[ p2pielen++ ] = 1;
++
++		//	Channel List
++		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
++	}
++	else
++	{
++		int i, j;
++		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++			//	Operating Class
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++			//	Number of Channels
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++			//	Channel List
++			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++			}
++		}
++	}
++#else // CONFIG_CONCURRENT_MODE
++	{
++		int i, j;
++		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++			//	Operating Class
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++			//	Number of Channels
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++			//	Channel List
++			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++			}
++		}
++	}
++#endif // CONFIG_CONCURRENT_MODE
++
++	//	Device Info
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
++
++	//	Length:
++	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
++	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
++	p2pielen += 2;
++
++	//	Value:
++	//	P2P Device Address
++	_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++	p2pielen += ETH_ALEN;
++
++	//	Config Method
++	//	This field should be big endian. Noted by P2P specification.
++
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
++
++	p2pielen += 2;
++
++	//	Primary Device Type
++	//	Category ID
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
++	p2pielen += 2;
++
++	//	OUI
++	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
++	p2pielen += 4;
++
++	//	Sub Category ID
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
++	p2pielen += 2;
++
++	//	Number of Secondary Device Types
++	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
++
++	//	Device Name
++	//	Type:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++	p2pielen += 2;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
++	p2pielen += 2;
++
++	//	Value:
++	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
++	p2pielen += pwdinfo->device_name_len;
++
++	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
++	{
++		//	Group ID Attribute
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
++
++		//	Length:
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
++		p2pielen += 2;
++
++		//	Value:
++		//	p2P Device Address
++		_rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
++		p2pielen += ETH_ALEN;
++
++		//	SSID
++		_rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
++		p2pielen += pwdinfo->nego_ssidlen;
++
++	}
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++#ifdef CONFIG_WFD
++	wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
++	pframe += wfdielen;
++	pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
++{
++
++	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
++	u8			action = P2P_PUB_ACTION_ACTION;
++	u32			p2poui = cpu_to_be32(P2POUI);
++	u8			oui_subtype = P2P_GO_NEGO_CONF;
++	u8			wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
++	u8			wpsielen = 0, p2pielen = 0;
++
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	DBG_871X( "[%s] In\n", __FUNCTION__ );
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
++
++
++
++	//	P2P IE Section.
++
++	//	P2P OUI
++	p2pielen = 0;
++	p2pie[ p2pielen++ ] = 0x50;
++	p2pie[ p2pielen++ ] = 0x6F;
++	p2pie[ p2pielen++ ] = 0x9A;
++	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++	//	Commented by Albert 20110306
++	//	According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes
++	//	1. Status
++	//	2. P2P Capability
++	//	3. Operating Channel
++	//	4. Channel List
++	//	5. Group ID	( if this WiFi is GO )
++
++	//	P2P Status
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = result;
++
++	//	P2P Capability
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Device Capability Bitmap, 1 byte
++	p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
++
++	//	Group Capability Bitmap, 1 byte
++	if ( pwdinfo->persistent_supported )
++	{
++		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
++	}
++	else
++	{
++		p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
++	}
++
++
++	//	Operating Channel
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++
++	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
++	{
++		if ( pwdinfo->peer_operating_ch <= 14 )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++		else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x73;
++		}
++		else
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x7c;
++		}
++
++		p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
++	}
++	else
++	{
++		if ( pwdinfo->operating_channel <= 14 )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++		else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x73;
++		}
++		else
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x7c;
++		}
++
++		//	Channel Number
++		p2pie[ p2pielen++ ] = pwdinfo->operating_channel;		//	Use the listen channel as the operating channel
++	}
++
++
++	//	Channel List
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
++
++	*(u16*) ( p2pie + p2pielen ) = 6;
++	p2pielen += 2;
++
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Value:
++	if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
++	{
++		if ( pwdinfo->peer_operating_ch <= 14 )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++		else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x73;
++		}
++		else
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x7c;
++		}
++		p2pie[ p2pielen++ ] = 1;
++		p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
++	}
++	else
++	{
++		if ( pwdinfo->operating_channel <= 14 )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++		else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x73;
++		}
++		else
++		{
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x7c;
++		}
++
++		//	Channel Number
++		p2pie[ p2pielen++ ] = 1;
++		p2pie[ p2pielen++ ] = pwdinfo->operating_channel;		//	Use the listen channel as the operating channel
++	}
++
++	if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
++	{
++		//	Group ID Attribute
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
++
++		//	Length:
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
++		p2pielen += 2;
++
++		//	Value:
++		//	p2P Device Address
++		_rtw_memcpy( p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
++		p2pielen += ETH_ALEN;
++
++		//	SSID
++		_rtw_memcpy( p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
++		p2pielen += pwdinfo->nego_ssidlen;
++	}
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++#ifdef CONFIG_WFD
++	wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
++	pframe += wfdielen;
++	pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
++{
++
++	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
++	u8			action = P2P_PUB_ACTION_ACTION;
++	u32			p2poui = cpu_to_be32(P2POUI);
++	u8			oui_subtype = P2P_INVIT_REQ;
++	u8			p2pie[ 255 ] = { 0x00 };
++	u8			p2pielen = 0, i;
++	u8			dialogToken = 3;
++	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
++	u16			len_channellist_attr = 0;
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++#ifdef CONFIG_CONCURRENT_MODE
++	_adapter				*pbuddy_adapter = padapter->pbuddy_adapter;
++	struct wifidirect_info	*pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
++	struct mlme_priv		*pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
++	struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++#endif
++
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
++
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
++
++	//	P2P IE Section.
++
++	//	P2P OUI
++	p2pielen = 0;
++	p2pie[ p2pielen++ ] = 0x50;
++	p2pie[ p2pielen++ ] = 0x6F;
++	p2pie[ p2pielen++ ] = 0x9A;
++	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++	//	Commented by Albert 20101011
++	//	According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes
++	//	1. Configuration Timeout
++	//	2. Invitation Flags
++	//	3. Operating Channel	( Only GO )
++	//	4. P2P Group BSSID	( Should be included if I am the GO )
++	//	5. Channel List
++	//	6. P2P Group ID
++	//	7. P2P Device Info
++
++	//	Configuration Timeout
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
++
++	//	Invitation Flags
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
++
++
++	//	Operating Channel
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Operating Class
++	if ( pwdinfo->invitereq_info.operating_ch <= 14 )
++		p2pie[ p2pielen++ ] = 0x51;
++	else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
++		p2pie[ p2pielen++ ] = 0x73;
++	else
++		p2pie[ p2pielen++ ] = 0x7c;
++
++	//	Channel Number
++	p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch;	//	operating channel number
++
++	if ( _rtw_memcmp( myid( &padapter->eeprompriv ), pwdinfo->invitereq_info.go_bssid, ETH_ALEN ) )
++	{
++		//	P2P Group BSSID
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
++
++		//	Length:
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
++		p2pielen += 2;
++
++		//	Value:
++		//	P2P Device Address for GO
++		_rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
++		p2pielen += ETH_ALEN;
++	}
++
++	//	Channel List
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
++
++
++	//	Length:
++	// Country String(3)
++	// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
++	// + number of channels in all classes
++	len_channellist_attr = 3
++	   + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
++	   + get_reg_classes_full_count(pmlmeext->channel_list);
++
++#ifdef CONFIG_CONCURRENT_MODE
++	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++	{
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
++	}
++	else
++	{
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++	}
++#else
++
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++
++ #endif
++	p2pielen += 2;
++
++	//	Value:
++	//	Country String
++	p2pie[ p2pielen++ ] = 'X';
++	p2pie[ p2pielen++ ] = 'X';
++
++	//	The third byte should be set to 0x04.
++	//	Described in the "Operating Channel Attribute" section.
++	p2pie[ p2pielen++ ] = 0x04;
++
++	//	Channel Entry List
++#ifdef CONFIG_CONCURRENT_MODE
++	if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++	{
++		_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++		struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++
++		//	Operating Class
++		if ( pbuddy_mlmeext->cur_channel > 14 )
++		{
++			if ( pbuddy_mlmeext->cur_channel >= 149 )
++			{
++				p2pie[ p2pielen++ ] = 0x7c;
++			}
++			else
++			{
++				p2pie[ p2pielen++ ] = 0x73;
++			}
++		}
++		else
++		{
++			p2pie[ p2pielen++ ] = 0x51;
++		}
++
++		//	Number of Channels
++		//	Just support 1 channel and this channel is AP's channel
++		p2pie[ p2pielen++ ] = 1;
++
++		//	Channel List
++		p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
++	}
++	else
++	{
++		int i, j;
++		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++			//	Operating Class
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++			//	Number of Channels
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++			//	Channel List
++			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++			}
++		}
++	}
++#else // CONFIG_CONCURRENT_MODE
++	{
++		int i, j;
++		for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++			//	Operating Class
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++			//	Number of Channels
++			p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++			//	Channel List
++			for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++			}
++		}
++	}
++#endif // CONFIG_CONCURRENT_MODE
++
++
++	//	P2P Group ID
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
++	p2pielen += 2;
++
++	//	Value:
++	//	P2P Device Address for GO
++	_rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
++	p2pielen += ETH_ALEN;
++
++	//	SSID
++	_rtw_memcpy( p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
++	p2pielen += pwdinfo->invitereq_info.ssidlen;
++
++
++	//	Device Info
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
++
++	//	Length:
++	//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
++	//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
++	p2pielen += 2;
++
++	//	Value:
++	//	P2P Device Address
++	_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++	p2pielen += ETH_ALEN;
++
++	//	Config Method
++	//	This field should be big endian. Noted by P2P specification.
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
++	p2pielen += 2;
++
++	//	Primary Device Type
++	//	Category ID
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
++	p2pielen += 2;
++
++	//	OUI
++	*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
++	p2pielen += 4;
++
++	//	Sub Category ID
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
++	p2pielen += 2;
++
++	//	Number of Secondary Device Types
++	p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
++
++	//	Device Name
++	//	Type:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++	p2pielen += 2;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
++	p2pielen += 2;
++
++	//	Value:
++	_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
++	p2pielen += pwdinfo->device_name_len;
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++#ifdef CONFIG_WFD
++	wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
++	pframe += wfdielen;
++	pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
++{
++
++	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
++	u8			action = P2P_PUB_ACTION_ACTION;
++	u32			p2poui = cpu_to_be32(P2POUI);
++	u8			oui_subtype = P2P_INVIT_RESP;
++	u8			p2pie[ 255 ] = { 0x00 };
++	u8			p2pielen = 0, i;
++	u8			channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
++	u16			len_channellist_attr = 0;
++#ifdef CONFIG_CONCURRENT_MODE
++	_adapter				*pbuddy_adapter = padapter->pbuddy_adapter;
++	struct wifidirect_info	*pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
++	struct mlme_priv		*pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
++	struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++#endif
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct wifidirect_info	*pwdinfo = &( padapter->wdinfo);
++
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, raddr,  ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
++
++	//	P2P IE Section.
++
++	//	P2P OUI
++	p2pielen = 0;
++	p2pie[ p2pielen++ ] = 0x50;
++	p2pie[ p2pielen++ ] = 0x6F;
++	p2pie[ p2pielen++ ] = 0x9A;
++	p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++	//	Commented by Albert 20101005
++	//	According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes
++	//	1. Status
++	//	2. Configuration Timeout
++	//	3. Operating Channel	( Only GO )
++	//	4. P2P Group BSSID	( Only GO )
++	//	5. Channel List
++
++	//	P2P Status
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
++	p2pielen += 2;
++
++	//	Value:
++	//	When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE.
++	//	Sent the event receiving the P2P Invitation Req frame to DMP UI.
++	//	DMP had to compare the MAC address to find out the profile.
++	//	So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB.
++	//	If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req
++	//	to NB to rebuild the persistent group.
++	p2pie[ p2pielen++ ] = status_code;
++
++	//	Configuration Timeout
++	//	Type:
++	p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
++
++	//	Length:
++	*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++	p2pielen += 2;
++
++	//	Value:
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P GO
++	p2pie[ p2pielen++ ] = 200;	//	2 seconds needed to be the P2P Client
++
++	if( status_code == P2P_STATUS_SUCCESS )
++	{
++		if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
++		{
++			//	The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO
++			//	In this case, the P2P Invitation response frame should carry the two more P2P attributes.
++			//	First one is operating channel attribute.
++			//	Second one is P2P Group BSSID attribute.
++
++			//	Operating Channel
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++			p2pielen += 2;
++
++			//	Value:
++			//	Country String
++			p2pie[ p2pielen++ ] = 'X';
++			p2pie[ p2pielen++ ] = 'X';
++
++			//	The third byte should be set to 0x04.
++			//	Described in the "Operating Channel Attribute" section.
++			p2pie[ p2pielen++ ] = 0x04;
++
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
++
++			//	Channel Number
++			p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
++
++
++			//	P2P Group BSSID
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
++			p2pielen += 2;
++
++			//	Value:
++			//	P2P Device Address for GO
++			_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++			p2pielen += ETH_ALEN;
++
++		}
++
++		//	Channel List
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
++
++		//	Length:
++		// Country String(3)
++		// + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?)
++		// + number of channels in all classes
++		len_channellist_attr = 3
++			+ (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
++			+ get_reg_classes_full_count(pmlmeext->channel_list);
++
++#ifdef CONFIG_CONCURRENT_MODE
++		if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++		{
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
++		}
++		else
++		{
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++		}
++#else
++
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
++
++#endif
++		p2pielen += 2;
++
++		//	Value:
++		//	Country String
++		p2pie[ p2pielen++ ] = 'X';
++		p2pie[ p2pielen++ ] = 'X';
++
++		//	The third byte should be set to 0x04.
++		//	Described in the "Operating Channel Attribute" section.
++		p2pie[ p2pielen++ ] = 0x04;
++
++		//	Channel Entry List
++#ifdef CONFIG_CONCURRENT_MODE
++		if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++		{
++			_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++			struct mlme_ext_priv	*pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++
++			//	Operating Class
++			if ( pbuddy_mlmeext->cur_channel > 14 )
++			{
++				if ( pbuddy_mlmeext->cur_channel >= 149 )
++				{
++					p2pie[ p2pielen++ ] = 0x7c;
++				}
++				else
++				{
++					p2pie[ p2pielen++ ] = 0x73;
++				}
++			}
++			else
++			{
++				p2pie[ p2pielen++ ] = 0x51;
++			}
++
++			//	Number of Channels
++			//	Just support 1 channel and this channel is AP's channel
++			p2pie[ p2pielen++ ] = 1;
++
++			//	Channel List
++			p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
++		}
++		else
++		{
++			int i, j;
++			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++				//	Operating Class
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++				//	Number of Channels
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++				//	Channel List
++				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++				}
++			}
++		}
++#else // CONFIG_CONCURRENT_MODE
++		{
++			int i, j;
++			for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
++				//	Operating Class
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
++
++				//	Number of Channels
++				p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
++
++				//	Channel List
++				for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
++					p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
++				}
++			}
++		}
++#endif // CONFIG_CONCURRENT_MODE
++	}
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++#ifdef CONFIG_WFD
++	wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
++	pframe += wfdielen;
++	pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
++{
++	unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
++	u8			action = P2P_PUB_ACTION_ACTION;
++	u8			dialogToken = 1;
++	u32			p2poui = cpu_to_be32(P2POUI);
++	u8			oui_subtype = P2P_PROVISION_DISC_REQ;
++	u8			wpsie[ 100 ] = { 0x00 };
++	u8			wpsielen = 0;
++	u32			p2pielen = 0;
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	DBG_871X( "[%s] In\n", __FUNCTION__ );
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
++
++	p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
++
++	pframe += p2pielen;
++	pattrib->pktlen += p2pielen;
++
++	wpsielen = 0;
++	//	WPS OUI
++	*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
++	wpsielen += 4;
++
++	//	WPS version
++	//	Type:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
++	wpsielen += 2;
++
++	//	Length:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++	wpsielen += 2;
++
++	//	Value:
++	wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
++
++	//	Config Method
++	//	Type:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
++	wpsielen += 2;
++
++	//	Length:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
++	wpsielen += 2;
++
++	//	Value:
++	*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
++	wpsielen += 2;
++
++	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
++
++
++#ifdef CONFIG_WFD
++	wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
++	pframe += wfdielen;
++	pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++
++u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
++{
++	u8 i, match_result = 0;
++
++	DBG_871X( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
++		    peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
++
++	for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
++	{
++	       DBG_871X( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
++			    profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
++		if ( _rtw_memcmp( peermacaddr, profileinfo->peermac, ETH_ALEN ) )
++		{
++			match_result = 1;
++			DBG_871X( "[%s] Match!\n", __FUNCTION__ );
++			break;
++		}
++	}
++
++	return (match_result );
++}
++
++void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
++{
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	unsigned char					*mac;
++	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	//WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
++	u16					beacon_interval = 100;
++	u16					capInfo = 0;
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++	u8					wpsie[255] = { 0x00 };
++	u32					wpsielen = 0, p2pielen = 0;
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++#ifdef CONFIG_INTEL_WIDI
++	u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
++#endif //CONFIG_INTEL_WIDI
++
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	mac = myid(&(padapter->eeprompriv));
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
++
++	//	Use the device address for BSSID field.
++	_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(fctrl, WIFI_PROBERSP);
++
++	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = pattrib->hdrlen;
++	pframe += pattrib->hdrlen;
++
++	//timestamp will be inserted by hardware
++	pframe += 8;
++	pattrib->pktlen += 8;
++
++	// beacon interval: 2 bytes
++	_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
++	pframe += 2;
++	pattrib->pktlen += 2;
++
++	//	capability info: 2 bytes
++	//	ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec)
++	capInfo |= cap_ShortPremble;
++	capInfo |= cap_ShortSlot;
++
++	_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
++	pframe += 2;
++	pattrib->pktlen += 2;
++
++
++	// SSID
++	pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
++
++	// supported rates...
++	//	Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
++	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
++
++	// DS parameter set
++	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
++
++#ifdef CONFIG_IOCTL_CFG80211
++	if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++	{
++		if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
++		{
++			//WPS IE
++			_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
++			pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
++			pframe += pmlmepriv->wps_probe_resp_ie_len;
++
++			//P2P IE
++			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
++			pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
++			pframe += pmlmepriv->p2p_probe_resp_ie_len;
++		}
++	}
++	else
++#endif //CONFIG_IOCTL_CFG80211
++	{
++
++		//	Todo: WPS IE
++		//	Noted by Albert 20100907
++		//	According to the WPS specification, all the WPS attribute is presented by Big Endian.
++
++		wpsielen = 0;
++		//	WPS OUI
++		*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
++		wpsielen += 4;
++
++		//	WPS version
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++		wpsielen += 2;
++
++		//	Value:
++		wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
++
++#ifdef CONFIG_INTEL_WIDI
++		//	Commented by Kurt
++		//	Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
++		if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
++			|| pmlmepriv->num_p2p_sdt != 0 )
++		{
++			//Sec dev type
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
++			wpsielen += 2;
++
++			//	Length:
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
++			wpsielen += 2;
++
++			//	Value:
++			//	Category ID
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
++			wpsielen += 2;
++
++			//	OUI
++			*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
++			wpsielen += 4;
++
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
++			wpsielen += 2;
++
++			if(  _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
++			{
++				//	Vendor Extension
++				_rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
++				wpsielen += L2SDTA_SERVICE_VE_LEN;
++			}
++		}
++#endif //CONFIG_INTEL_WIDI
++
++		//	WiFi Simple Config State
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++		wpsielen += 2;
++
++		//	Value:
++		wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;	//	Not Configured.
++
++		//	Response Type
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++		wpsielen += 2;
++
++		//	Value:
++		wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
++
++		//	UUID-E
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
++		wpsielen += 2;
++
++		//	Value:
++		if (pwdinfo->external_uuid == 0) {
++			_rtw_memset( wpsie + wpsielen, 0x0, 16 );
++			_rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++		} else {
++			_rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
++		}
++		wpsielen += 0x10;
++
++		//	Manufacturer
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
++		wpsielen += 2;
++
++		//	Value:
++		_rtw_memcpy( wpsie + wpsielen, "Realtek", 7 );
++		wpsielen += 7;
++
++		//	Model Name
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
++		wpsielen += 2;
++
++		//	Value:
++		_rtw_memcpy( wpsie + wpsielen, "8192CU", 6 );
++		wpsielen += 6;
++
++		//	Model Number
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++		wpsielen += 2;
++
++		//	Value:
++		wpsie[ wpsielen++ ] = 0x31;		//	character 1
++
++		//	Serial Number
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
++		wpsielen += 2;
++
++		//	Value:
++		_rtw_memcpy( wpsie + wpsielen, "123456" , ETH_ALEN );
++		wpsielen += ETH_ALEN;
++
++		//	Primary Device Type
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
++		wpsielen += 2;
++
++		//	Value:
++		//	Category ID
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
++		wpsielen += 2;
++
++		//	OUI
++		*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
++		wpsielen += 4;
++
++		//	Sub Category ID
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
++		wpsielen += 2;
++
++		//	Device Name
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
++		wpsielen += 2;
++
++		//	Value:
++		_rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
++		wpsielen += pwdinfo->device_name_len;
++
++		//	Config Method
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
++		wpsielen += 2;
++
++		//	Value:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
++		wpsielen += 2;
++
++
++		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
++
++
++		p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
++		pframe += p2pielen;
++		pattrib->pktlen += p2pielen;
++	}
++
++#ifdef CONFIG_WFD
++#ifdef CONFIG_IOCTL_CFG80211
++	if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
++#endif //CONFIG_IOCTL_CFG80211
++	{
++		wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
++		pframe += wfdielen;
++		pattrib->pktlen += wfdielen;
++	}
++#ifdef CONFIG_IOCTL_CFG80211
++	else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
++	{
++		//WFD IE
++		_rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
++		pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
++		pframe += pmlmepriv->wfd_probe_resp_ie_len;
++	}
++#endif //CONFIG_IOCTL_CFG80211
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
++{
++	int ret = _FAIL;
++	struct xmit_frame		*pmgntframe;
++	struct pkt_attrib		*pattrib;
++	unsigned char			*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short		*fctrl;
++	unsigned char			*mac;
++	unsigned char			bssrate[NumRates];
++	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	int	bssrate_len = 0;
++	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++	u8					wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
++	u16					wpsielen = 0, p2pielen = 0;
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		goto exit;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	mac = myid(&(padapter->eeprompriv));
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	if (da) {
++		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
++	} else {
++		if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
++		{
++			//	This two flags will be set when this is only the P2P client mode.
++			_rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
++			_rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
++		}
++		else
++		{
++			//	broadcast probe request frame
++			_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
++			_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
++		}
++	}
++	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_PROBEREQ);
++
++	pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
++
++	if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
++	{
++		pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
++	}
++	else
++	{
++		pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
++	}
++	//	Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 )
++	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
++
++#ifdef CONFIG_IOCTL_CFG80211
++	if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++	{
++		if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
++		{
++			//WPS IE
++			_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
++			pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
++			pframe += pmlmepriv->wps_probe_req_ie_len;
++
++			//P2P IE
++			_rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
++			pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
++			pframe += pmlmepriv->p2p_probe_req_ie_len;
++		}
++	}
++	else
++#endif //CONFIG_IOCTL_CFG80211
++	{
++
++		//	WPS IE
++		//	Noted by Albert 20110221
++		//	According to the WPS specification, all the WPS attribute is presented by Big Endian.
++
++		wpsielen = 0;
++		//	WPS OUI
++		*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
++		wpsielen += 4;
++
++		//	WPS version
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
++		wpsielen += 2;
++
++		//	Value:
++		wpsie[wpsielen++] = WPS_VERSION_1;	//	Version 1.0
++
++		if( pmlmepriv->wps_probe_req_ie == NULL )
++		{
++			//	UUID-E
++			//	Type:
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
++			wpsielen += 2;
++
++			//	Length:
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
++			wpsielen += 2;
++
++			//	Value:
++			if (pwdinfo->external_uuid == 0) {
++				_rtw_memset( wpsie + wpsielen, 0x0, 16 );
++				_rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++			} else {
++				_rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
++			}
++			wpsielen += 0x10;
++
++			//	Config Method
++			//	Type:
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
++			wpsielen += 2;
++
++			//	Length:
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
++			wpsielen += 2;
++
++			//	Value:
++			*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
++			wpsielen += 2;
++		}
++
++		//	Device Name
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
++		wpsielen += 2;
++
++		//	Value:
++		_rtw_memcpy( wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
++		wpsielen += pwdinfo->device_name_len;
++
++		//	Primary Device Type
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
++		wpsielen += 2;
++
++		//	Value:
++		//	Category ID
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
++		wpsielen += 2;
++
++		//	OUI
++		*(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
++		wpsielen += 4;
++
++		//	Sub Category ID
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
++		wpsielen += 2;
++
++		//	Device Password ID
++		//	Type:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
++		wpsielen += 2;
++
++		//	Length:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
++		wpsielen += 2;
++
++		//	Value:
++		*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );	//	Registrar-specified
++		wpsielen += 2;
++
++		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
++
++		//	P2P OUI
++		p2pielen = 0;
++		p2pie[ p2pielen++ ] = 0x50;
++		p2pie[ p2pielen++ ] = 0x6F;
++		p2pie[ p2pielen++ ] = 0x9A;
++		p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++		//	Commented by Albert 20110221
++		//	According to the P2P Specification, the probe request frame should contain 5 P2P attributes
++		//	1. P2P Capability
++		//	2. P2P Device ID if this probe request wants to find the specific P2P device
++		//	3. Listen Channel
++		//	4. Extended Listen Timing
++		//	5. Operating Channel if this WiFi is working as the group owner now
++
++		//	P2P Capability
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
++
++		//	Length:
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++		p2pielen += 2;
++
++		//	Value:
++		//	Device Capability Bitmap, 1 byte
++		p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
++
++		//	Group Capability Bitmap, 1 byte
++		if ( pwdinfo->persistent_supported )
++			p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
++		else
++			p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
++
++		//	Listen Channel
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
++
++		//	Length:
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++		p2pielen += 2;
++
++		//	Value:
++		//	Country String
++		p2pie[ p2pielen++ ] = 'X';
++		p2pie[ p2pielen++ ] = 'X';
++
++		//	The third byte should be set to 0x04.
++		//	Described in the "Operating Channel Attribute" section.
++		p2pie[ p2pielen++ ] = 0x04;
++
++		//	Operating Class
++		p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
++
++		//	Channel Number
++		p2pie[ p2pielen++ ] = pwdinfo->listen_channel;	//	listen channel
++
++
++		//	Extended Listen Timing
++		//	Type:
++		p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
++
++		//	Length:
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
++		p2pielen += 2;
++
++		//	Value:
++		//	Availability Period
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
++		p2pielen += 2;
++
++		//	Availability Interval
++		*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
++		p2pielen += 2;
++
++		if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
++		{
++			//	Operating Channel (if this WiFi is working as the group owner now)
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
++			p2pielen += 2;
++
++			//	Value:
++			//	Country String
++			p2pie[ p2pielen++ ] = 'X';
++			p2pie[ p2pielen++ ] = 'X';
++
++			//	The third byte should be set to 0x04.
++			//	Described in the "Operating Channel Attribute" section.
++			p2pie[ p2pielen++ ] = 0x04;
++
++			//	Operating Class
++			p2pie[ p2pielen++ ] = 0x51;	//	Copy from SD7
++
++			//	Channel Number
++			p2pie[ p2pielen++ ] = pwdinfo->operating_channel;	//	operating channel number
++
++		}
++
++		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++		if( pmlmepriv->wps_probe_req_ie != NULL )
++		{
++			//WPS IE
++			_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
++			pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
++			pframe += pmlmepriv->wps_probe_req_ie_len;
++		}
++	}
++
++#ifdef CONFIG_WFD
++#ifdef CONFIG_IOCTL_CFG80211
++	if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
++#endif
++	{
++		wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
++		pframe += wfdielen;
++		pattrib->pktlen += wfdielen;
++	}
++#ifdef CONFIG_IOCTL_CFG80211
++	else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
++	{
++		//WFD IE
++		_rtw_memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
++		pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
++		pframe += pmlmepriv->wfd_probe_req_ie_len;
++	}
++#endif //CONFIG_IOCTL_CFG80211
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
++
++	if (wait_ack) {
++		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
++	} else {
++		dump_mgntframe(padapter, pmgntframe);
++		ret = _SUCCESS;
++	}
++
++exit:
++	return ret;
++}
++
++inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
++{
++	_issue_probereq_p2p(adapter, da, _FALSE);
++}
++
++int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
++{
++	int ret;
++	int i = 0;
++	u32 start = rtw_get_current_time();
++
++	do
++	{
++		ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
++
++		i++;
++
++		if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
++			break;
++
++		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
++			rtw_msleep_os(wait_ms);
++
++	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
++
++	if (ret != _FAIL) {
++		ret = _SUCCESS;
++		#ifndef DBG_XMIT_ACK
++		goto exit;
++		#endif
++	}
++
++	if (try_cnt && wait_ms) {
++		if (da)
++			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++		else
++			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++	}
++exit:
++	return ret;
++}
++
++#endif //CONFIG_P2P
++
++s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
++{
++	_adapter *adapter = recv_frame->u.hdr.adapter;
++	struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
++	u8 *frame = recv_frame->u.hdr.rx_data;
++	u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
++		(recv_frame->u.hdr.attrib.frag_num & 0xf);
++
++	if (GetRetry(frame)) {
++		if (token >= 0) {
++			if ((seq_ctrl == mlmeext->action_public_rxseq)
++				&& (token == mlmeext->action_public_dialog_token))
++			{
++				DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
++					FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
++				return _FAIL;
++			}
++		} else {
++			if (seq_ctrl == mlmeext->action_public_rxseq) {
++				DBG_871X(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
++					FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
++				return _FAIL;
++			}
++		}
++	}
++
++	mlmeext->action_public_rxseq = seq_ctrl;
++
++	if (token >= 0)
++		mlmeext->action_public_dialog_token = token;
++
++	return _SUCCESS;
++}
++
++unsigned int on_action_public_p2p(union recv_frame *precv_frame)
++{
++	_adapter *padapter = precv_frame->u.hdr.adapter;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint len = precv_frame->u.hdr.len;
++	u8 *frame_body;
++	u8 dialogToken=0;
++#ifdef CONFIG_P2P
++	u8 *p2p_ie;
++	u32	p2p_ielen, wps_ielen;
++	struct	wifidirect_info	*pwdinfo = &( padapter->wdinfo );
++	u8	result = P2P_STATUS_SUCCESS;
++	u8	empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
++	u8 *merged_p2pie = NULL;
++	u32 merged_p2p_ielen = 0;
++#endif //CONFIG_P2P
++
++	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
++
++	dialogToken = frame_body[7];
++
++	if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
++		return _FAIL;
++
++#ifdef CONFIG_P2P
++	_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
++#ifdef CONFIG_IOCTL_CFG80211
++	if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
++	{
++		rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
++	}
++	else
++#endif //CONFIG_IOCTL_CFG80211
++	{
++		//	Do nothing if the driver doesn't enable the P2P function.
++		if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
++			return _SUCCESS;
++
++		len -= sizeof(struct rtw_ieee80211_hdr_3addr);
++
++		switch( frame_body[ 6 ] )//OUI Subtype
++		{
++			case P2P_GO_NEGO_REQ:
++			{
++				DBG_871X( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
++				_rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
++
++				if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
++				{
++					rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
++				}
++
++				if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
++				{
++					//	Commented by Albert 20110526
++					//	In this case, this means the previous nego fail doesn't be reset yet.
++					_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
++					//	Restore the previous p2p state
++					rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
++					DBG_871X( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
++				}
++#ifdef CONFIG_CONCURRENT_MODE
++				if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++				{
++					_cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
++				}
++#endif // CONFIG_CONCURRENT_MODE
++
++				//	Commented by Kurt 20110902
++				//Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
++				if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
++					rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
++
++				//	Commented by Kurt 20120113
++				//	Get peer_dev_addr here if peer doesn't issue prov_disc frame.
++				if( _rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN) );
++					_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
++
++				result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
++				issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
++#ifdef CONFIG_INTEL_WIDI
++				if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
++				{
++					padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
++					_cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
++					intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
++				}
++#endif //CONFIG_INTEL_WIDI
++
++				//	Commented by Albert 20110718
++				//	No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer.
++#ifdef CONFIG_CONCURRENT_MODE
++				//	Commented by Albert 20120107
++				_set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
++#else // CONFIG_CONCURRENT_MODE
++				_set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
++#endif // CONFIG_CONCURRENT_MODE
++				break;
++			}
++			case P2P_GO_NEGO_RESP:
++			{
++				DBG_871X( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
++
++				if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
++				{
++					//	Commented by Albert 20110425
++					//	The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function.
++					_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
++					pwdinfo->nego_req_info.benable = _FALSE;
++					result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
++					issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
++					if ( P2P_STATUS_SUCCESS == result )
++					{
++						if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
++						{
++							pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
++							#ifdef P2P_OP_CHECK_SOCIAL_CH
++							pwdinfo->p2p_info.operation_ch[ 1 ] = 1;	//Check whether GO is operating in channel 1;
++							pwdinfo->p2p_info.operation_ch[ 2 ] = 6;	//Check whether GO is operating in channel 6;
++							pwdinfo->p2p_info.operation_ch[ 3 ] = 11;	//Check whether GO is operating in channel 11;
++							#endif //P2P_OP_CHECK_SOCIAL_CH
++							pwdinfo->p2p_info.scan_op_ch_only = 1;
++							_set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
++						}
++					}
++
++					//	Reset the dialog token for group negotiation frames.
++					pwdinfo->negotiation_dialog_token = 1;
++
++					if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
++					{
++						_set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
++					}
++				}
++				else
++				{
++					DBG_871X( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
++				}
++
++				break;
++			}
++			case P2P_GO_NEGO_CONF:
++			{
++				DBG_871X( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
++				result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
++				if ( P2P_STATUS_SUCCESS == result )
++				{
++					if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
++					{
++						pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
++						#ifdef P2P_OP_CHECK_SOCIAL_CH
++						pwdinfo->p2p_info.operation_ch[ 1 ] = 1;	//Check whether GO is operating in channel 1;
++						pwdinfo->p2p_info.operation_ch[ 2 ] = 6;	//Check whether GO is operating in channel 6;
++						pwdinfo->p2p_info.operation_ch[ 3 ] = 11;	//Check whether GO is operating in channel 11;
++						#endif //P2P_OP_CHECK_SOCIAL_CH
++						pwdinfo->p2p_info.scan_op_ch_only = 1;
++						_set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
++					}
++				}
++				break;
++			}
++			case P2P_INVIT_REQ:
++			{
++				//	Added by Albert 2010/10/05
++				//	Received the P2P Invite Request frame.
++
++				DBG_871X( "[%s] Got invite request frame!\n", __FUNCTION__ );
++				if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
++				{
++					//	Parse the necessary information from the P2P Invitation Request frame.
++					//	For example: The MAC address of sending this P2P Invitation Request frame.
++					u32	attr_contentlen = 0;
++					u8	status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
++					struct group_id_info group_id;
++					u8	invitation_flag = 0;
++
++					merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
++
++					merged_p2pie = rtw_malloc(merged_p2p_ielen);
++					if (merged_p2pie == NULL)
++					{
++						DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
++						goto exit;
++					}
++					_rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
++
++					merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
++
++					rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
++					if ( attr_contentlen )
++					{
++
++						rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
++						//	Commented by Albert 20120510
++						//	Copy to the pwdinfo->p2p_peer_interface_addr.
++						//	So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
++						//	#> iwpriv wlan0 p2p_get peer_ifa
++						//	After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant.
++
++						if ( attr_contentlen )
++						{
++							DBG_871X( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
++									pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
++									pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
++									pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
++						}
++
++						if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
++						{
++							//	Re-invoke the persistent group.
++
++							_rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
++							rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
++							if ( attr_contentlen )
++							{
++								if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
++								{
++									//	The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO.
++									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
++									rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
++									status_code = P2P_STATUS_SUCCESS;
++								}
++								else
++								{
++									//	The p2p device sending this p2p invitation request wants to be the persistent GO.
++									if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
++									{
++										u8 operatingch_info[5] = { 0x00 };
++
++										if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
++										{
++											if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) >= 0 )
++											{
++												//	The operating channel is acceptable for this device.
++												pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
++												#ifdef P2P_OP_CHECK_SOCIAL_CH
++												pwdinfo->rx_invitereq_info.operation_ch[1]= 1;		//Check whether GO is operating in channel 1;
++												pwdinfo->rx_invitereq_info.operation_ch[2]= 6;		//Check whether GO is operating in channel 6;
++												pwdinfo->rx_invitereq_info.operation_ch[3]= 11;		//Check whether GO is operating in channel 11;
++												#endif //P2P_OP_CHECK_SOCIAL_CH
++												pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
++												_set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
++												rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
++												rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
++												status_code = P2P_STATUS_SUCCESS;
++											}
++											else
++											{
++												//	The operating channel isn't supported by this device.
++												rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
++												rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
++												status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
++												_set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
++											}
++										}
++										else
++										{
++											//	Commented by Albert 20121130
++											//	Intel will use the different P2P IE to store the operating channel information
++											//	Workaround for Intel WiDi 3.5
++											rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
++											rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
++											status_code = P2P_STATUS_SUCCESS;
++										}
++									}
++									else
++									{
++										rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
++										#ifdef CONFIG_INTEL_WIDI
++										_rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
++										rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
++										#endif //CONFIG_INTEL_WIDI
++
++										status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
++									}
++								}
++							}
++							else
++							{
++								DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
++								status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
++							}
++						}
++						else
++						{
++							//	Received the invitation to join a P2P group.
++
++							_rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
++							rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
++							if ( attr_contentlen )
++							{
++								if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
++								{
++									//	In this case, the GO can't be myself.
++									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
++									status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
++								}
++								else
++								{
++									//	The p2p device sending this p2p invitation request wants to join an existing P2P group
++									//	Commented by Albert 2012/06/28
++									//	In this case, this Wi-Fi device should use the iwpriv command to get the peer device address.
++									//	The peer device address should be the destination address for the provisioning discovery request.
++									//	Then, this Wi-Fi device should use the iwpriv command to get the peer interface address.
++									//	The peer interface address should be the address for WPS mac address
++									_rtw_memcpy( pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
++									rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
++									rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
++									status_code = P2P_STATUS_SUCCESS;
++								}
++							}
++							else
++							{
++								DBG_871X( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
++								status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
++							}
++						}
++					}
++					else
++					{
++						DBG_871X( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
++						status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
++					}
++
++					DBG_871X( "[%s] status_code = %d\n", __FUNCTION__, status_code );
++
++					pwdinfo->inviteresp_info.token = frame_body[ 7 ];
++					issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
++					_set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
++				}
++#ifdef CONFIG_INTEL_WIDI
++				if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
++				{
++					padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
++					_cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
++					intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
++				}
++#endif //CONFIG_INTEL_WIDI
++				break;
++			}
++			case P2P_INVIT_RESP:
++			{
++				u8	attr_content = 0x00;
++				u32	attr_contentlen = 0;
++
++				DBG_871X( "[%s] Got invite response frame!\n", __FUNCTION__ );
++				_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
++				if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
++				{
++					rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
++
++					if ( attr_contentlen == 1 )
++					{
++						DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
++						pwdinfo->invitereq_info.benable = _FALSE;
++
++						if ( attr_content == P2P_STATUS_SUCCESS )
++						{
++							if ( _rtw_memcmp( pwdinfo->invitereq_info.go_bssid, myid( &padapter->eeprompriv ), ETH_ALEN ))
++							{
++								rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
++							}
++							else
++							{
++								rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
++							}
++							rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
++						}
++						else
++						{
++							rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
++							rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
++						}
++					}
++					else
++					{
++						rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
++						rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
++					}
++				}
++				else
++				{
++					rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
++					rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
++				}
++
++				if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
++				{
++					_set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
++				}
++				break;
++			}
++			case P2P_DEVDISC_REQ:
++
++				process_p2p_devdisc_req(pwdinfo, pframe, len);
++
++				break;
++
++			case P2P_DEVDISC_RESP:
++
++				process_p2p_devdisc_resp(pwdinfo, pframe, len);
++
++				break;
++
++			case P2P_PROVISION_DISC_REQ:
++				DBG_871X( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
++				process_p2p_provdisc_req(pwdinfo, pframe, len);
++				_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
++
++				//20110902 Kurt
++				//Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered.
++				if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
++					rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
++
++				rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
++				_set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
++#ifdef CONFIG_INTEL_WIDI
++				if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
++				{
++					padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
++					_cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
++					intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
++				}
++#endif //CONFIG_INTEL_WIDI
++				break;
++
++			case P2P_PROVISION_DISC_RESP:
++				//	Commented by Albert 20110707
++				//	Should we check the pwdinfo->tx_prov_disc_info.bsent flag here??
++				DBG_871X( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
++				//	Commented by Albert 20110426
++				//	The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function.
++				_cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
++				rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
++				process_p2p_provdisc_resp(pwdinfo, pframe);
++				_set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
++				break;
++
++		}
++	}
++#endif //CONFIG_P2P
++
++exit:
++
++	if(merged_p2pie)
++	{
++		rtw_mfree(merged_p2pie, merged_p2p_ielen);
++	}
++
++	return _SUCCESS;
++}
++
++unsigned int on_action_public_vendor(union recv_frame *precv_frame)
++{
++	unsigned int ret = _FAIL;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint frame_len = precv_frame->u.hdr.len;
++	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
++		ret = on_action_public_p2p(precv_frame);
++	}
++
++	return ret;
++}
++
++unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
++{
++	unsigned int ret = _FAIL;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint frame_len = precv_frame->u.hdr.len;
++	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
++	u8 token;
++	_adapter *adapter = precv_frame->u.hdr.adapter;
++	int cnt = 0;
++	char msg[64];
++
++	token = frame_body[2];
++
++	if (rtw_action_public_decache(precv_frame, token) == _FAIL)
++		goto exit;
++
++	#ifdef CONFIG_IOCTL_CFG80211
++	cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
++	rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
++	#endif
++
++	ret = _SUCCESS;
++
++exit:
++	return ret;
++}
++
++unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
++{
++	unsigned int ret = _FAIL;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint frame_len = precv_frame->u.hdr.len;
++	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
++	u8 category, action;
++
++	/* check RA matches or not */
++	if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))
++		goto exit;
++
++	category = frame_body[0];
++	if(category != RTW_WLAN_CATEGORY_PUBLIC)
++		goto exit;
++
++	action = frame_body[1];
++	switch (action) {
++	case ACT_PUBLIC_VENDOR:
++		ret = on_action_public_vendor(precv_frame);
++		break;
++	default:
++		ret = on_action_public_default(precv_frame, action);
++		break;
++	}
++
++exit:
++	return ret;
++}
++
++unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
++{
++	return _SUCCESS;
++}
++
++#ifdef CONFIG_IEEE80211W
++unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
++{
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	unsigned short tid;
++	//Baron
++
++	DBG_871X("OnAction_sa_query\n");
++
++	switch (pframe[WLAN_HDR_A3_LEN+1])
++	{
++		case 0: //SA Query req
++			_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short));
++			DBG_871X("OnAction_sa_query request,action=%d, tid=%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid);
++			issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid);
++			break;
++
++		case 1: //SA Query rsp
++			_cancel_timer_ex(&pmlmeext->sa_query_timer);
++			DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]);
++			break;
++		default:
++			break;
++	}
++	if(0)
++	{
++		int pp;
++		printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
++		for(pp=0;pp< pattrib->pkt_len; pp++)
++			printk(" %02x ", pframe[pp]);
++		printk("\n");
++	}
++
++	return _SUCCESS;
++}
++#endif //CONFIG_IEEE80211W
++
++unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
++{
++	return _SUCCESS;
++}
++
++unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
++{
++#ifdef CONFIG_P2P
++	u8 *frame_body;
++	u8 category, OUI_Subtype, dialogToken=0;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++	uint len = precv_frame->u.hdr.len;
++	struct	wifidirect_info	*pwdinfo = &( padapter->wdinfo );
++
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	//check RA matches or not
++	if (!_rtw_memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))//for if1, sta/ap mode
++		return _SUCCESS;
++
++	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
++
++	category = frame_body[0];
++	if(category != RTW_WLAN_CATEGORY_P2P)
++		return _SUCCESS;
++
++	if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
++		return _SUCCESS;
++
++#ifdef CONFIG_IOCTL_CFG80211
++	if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++	{
++		rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
++		return _SUCCESS;
++	}
++	else
++#endif //CONFIG_IOCTL_CFG80211
++	{
++		len -= sizeof(struct rtw_ieee80211_hdr_3addr);
++		OUI_Subtype = frame_body[5];
++		dialogToken = frame_body[6];
++
++		switch(OUI_Subtype)
++		{
++			case P2P_NOTICE_OF_ABSENCE:
++
++				break;
++
++			case P2P_PRESENCE_REQUEST:
++
++				process_p2p_presence_req(pwdinfo, pframe, len);
++
++				break;
++
++			case P2P_PRESENCE_RESPONSE:
++
++				break;
++
++			case P2P_GO_DISC_REQUEST:
++
++				break;
++
++			default:
++				break;
++
++		}
++	}
++#endif //CONFIG_P2P
++
++	return _SUCCESS;
++
++}
++
++unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
++{
++	int i;
++	unsigned char	category;
++	struct action_handler *ptable;
++	unsigned char	*frame_body;
++	u8 *pframe = precv_frame->u.hdr.rx_data;
++
++	frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
++
++	category = frame_body[0];
++
++	for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
++	{
++		ptable = &OnAction_tbl[i];
++
++		if(category == ptable->num)
++			ptable->func(padapter, precv_frame);
++
++	}
++
++	return _SUCCESS;
++
++}
++
++unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
++{
++
++	//DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe));
++	return _SUCCESS;
++}
++
++struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
++{
++	struct xmit_frame *pmgntframe;
++	struct xmit_buf *pxmitbuf;
++
++	if (once)
++		pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
++	else
++		pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
++
++	if (pmgntframe == NULL) {
++		DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
++		goto exit;
++	}
++
++	if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
++		DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
++		rtw_free_xmitframe(pxmitpriv, pmgntframe);
++		pmgntframe = NULL;
++		goto exit;
++	}
++
++	pmgntframe->frame_tag = MGNT_FRAMETAG;
++	pmgntframe->pxmitbuf = pxmitbuf;
++	pmgntframe->buf_addr = pxmitbuf->pbuf;
++	pxmitbuf->priv_data = pmgntframe;
++
++exit:
++	return pmgntframe;
++
++}
++
++inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
++{
++	return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
++}
++
++inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
++{
++	return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
++}
++
++
++/****************************************************************************
++
++Following are some TX fuctions for WiFi MLME
++
++*****************************************************************************/
++
++void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
++{
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++
++	pmlmeext->tx_rate = rate;
++
++	//DBG_871X("%s(): rate = %x\n",__FUNCTION__, rate);
++}
++
++void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
++{
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++
++	_rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
++
++	pattrib->hdrlen = 24;
++	pattrib->nr_frags = 1;
++	pattrib->priority = 7;
++	pattrib->mac_id = 0;
++	pattrib->qsel = 0x12;
++
++	pattrib->pktlen = 0;
++
++	if(pmlmeext->cur_wireless_mode & WIRELESS_11B)
++		pattrib->raid = 6;//b mode
++	else
++		pattrib->raid = 5;//a/g mode
++
++	pattrib->encrypt = _NO_PRIVACY_;
++	pattrib->bswenc = _FALSE;
++
++	pattrib->qos_en = _FALSE;
++	pattrib->ht_en = _FALSE;
++	pattrib->bwmode = HT_CHANNEL_WIDTH_20;
++	pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
++	pattrib->sgi = _FALSE;
++
++	pattrib->seqnum = pmlmeext->mgnt_seq;
++
++	pattrib->retry_ctrl = _TRUE;
++
++}
++
++void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
++{
++	if(padapter->bSurpriseRemoved == _TRUE ||
++		padapter->bDriverStopped == _TRUE)
++	{
++		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
++		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
++		return;
++	}
++
++	rtw_hal_mgnt_xmit(padapter, pmgntframe);
++}
++
++s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
++{
++	s32 ret = _FAIL;
++	_irqL irqL;
++	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
++	struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
++	struct submit_ctx sctx;
++
++	if(padapter->bSurpriseRemoved == _TRUE ||
++		padapter->bDriverStopped == _TRUE)
++	{
++		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
++		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
++		return ret;
++	}
++
++	rtw_sctx_init(&sctx, timeout_ms);
++	pxmitbuf->sctx = &sctx;
++
++	ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
++
++	if (ret == _SUCCESS)
++		ret = rtw_sctx_wait(&sctx);
++
++	_enter_critical(&pxmitpriv->lock_sctx, &irqL);
++	pxmitbuf->sctx = NULL;
++	_exit_critical(&pxmitpriv->lock_sctx, &irqL);
++
++	 return ret;
++}
++
++s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
++{
++#ifdef CONFIG_XMIT_ACK
++	s32 ret = _FAIL;
++	u32 timeout_ms = 500;//  500ms
++	struct xmit_priv	*pxmitpriv = &padapter->xmitpriv;
++	#ifdef CONFIG_CONCURRENT_MODE
++	if (padapter->pbuddy_adapter && !padapter->isprimary)
++		pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
++	#endif
++
++	if(padapter->bSurpriseRemoved == _TRUE ||
++		padapter->bDriverStopped == _TRUE)
++	{
++		rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
++		rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
++		return -1;
++	}
++
++	_enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
++	pxmitpriv->ack_tx = _TRUE;
++
++	pmgntframe->ack_report = 1;
++	if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
++		ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
++	}
++
++	pxmitpriv->ack_tx = _FALSE;
++	_exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
++
++	 return ret;
++#else //!CONFIG_XMIT_ACK
++	dump_mgntframe(padapter, pmgntframe);
++	rtw_msleep_os(50);
++	return _SUCCESS;
++#endif //!CONFIG_XMIT_ACK
++}
++
++int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
++{
++	u8 *ssid_ie;
++	sint ssid_len_ori;
++	int len_diff = 0;
++
++	ssid_ie = rtw_get_ie(ies,  WLAN_EID_SSID, &ssid_len_ori, ies_len);
++
++	//DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori);
++
++	if(ssid_ie && ssid_len_ori>0)
++	{
++		switch(hidden_ssid_mode)
++		{
++			case 1:
++			{
++				u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
++				u32 remain_len = 0;
++
++				remain_len = ies_len -(next_ie-ies);
++
++				ssid_ie[1] = 0;
++				_rtw_memcpy(ssid_ie+2, next_ie, remain_len);
++				len_diff -= ssid_len_ori;
++
++				break;
++			}
++			case 2:
++				_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
++				break;
++			default:
++				break;
++		}
++	}
++
++	return len_diff;
++}
++
++void issue_beacon(_adapter *padapter)
++{
++	struct xmit_frame	*pmgntframe;
++	struct pkt_attrib	*pattrib;
++	unsigned char	*pframe;
++	struct rtw_ieee80211_hdr *pwlanhdr;
++	unsigned short *fctrl;
++	unsigned int	rate_len;
++	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	_irqL irqL;
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
++	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++#endif //CONFIG_P2P
++
++
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
++		return;
++	}
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
++#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++	pattrib->qsel = 0x10;
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
++	//pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_BEACON);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
++
++	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
++	{
++		//DBG_871X("ie len=%d\n", cur_network->IELength);
++#ifdef CONFIG_P2P
++		// for P2P : Primary Device Type & Device Name
++		u32 wpsielen=0, insert_len=0;
++		u8 *wpsie=NULL;
++		wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
++
++		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
++		{
++			uint wps_offset, remainder_ielen;
++			u8 *premainder_ie, *pframe_wscie;
++
++			wps_offset = (uint)(wpsie - cur_network->IEs);
++
++			premainder_ie = wpsie + wpsielen;
++
++			remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
++
++#ifdef CONFIG_IOCTL_CFG80211
++			if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++			{
++				if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
++				{
++					_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
++					pframe += wps_offset;
++					pattrib->pktlen += wps_offset;
++
++					_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
++					pframe += pmlmepriv->wps_beacon_ie_len;
++					pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
++
++					//copy remainder_ie to pframe
++					_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
++					pframe += remainder_ielen;
++					pattrib->pktlen += remainder_ielen;
++				}
++				else
++				{
++					_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
++					pframe += cur_network->IELength;
++					pattrib->pktlen += cur_network->IELength;
++				}
++			}
++			else
++#endif //CONFIG_IOCTL_CFG80211
++			{
++				pframe_wscie = pframe + wps_offset;
++				_rtw_memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
++				pframe += (wps_offset + wpsielen);
++				pattrib->pktlen += (wps_offset + wpsielen);
++
++				//now pframe is end of wsc ie, insert Primary Device Type & Device Name
++				//	Primary Device Type
++				//	Type:
++				*(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
++				insert_len += 2;
++
++				//	Length:
++				*(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
++				insert_len += 2;
++
++				//	Value:
++				//	Category ID
++				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
++				insert_len += 2;
++
++				//	OUI
++				*(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
++				insert_len += 4;
++
++				//	Sub Category ID
++				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
++				insert_len += 2;
++
++
++				//	Device Name
++				//	Type:
++				*(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++				insert_len += 2;
++
++				//	Length:
++				*(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
++				insert_len += 2;
++
++				//	Value:
++				_rtw_memcpy( pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
++				insert_len += pwdinfo->device_name_len;
++
++
++				//update wsc ie length
++				*(pframe_wscie+1) = (wpsielen -2) + insert_len;
++
++				//pframe move to end
++				pframe+=insert_len;
++				pattrib->pktlen += insert_len;
++
++				//copy remainder_ie to pframe
++				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
++				pframe += remainder_ielen;
++				pattrib->pktlen += remainder_ielen;
++			}
++		}
++		else
++#endif //CONFIG_P2P
++		{
++			int len_diff;
++			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
++			len_diff = update_hidden_ssid(
++				pframe+_BEACON_IE_OFFSET_
++				, cur_network->IELength-_BEACON_IE_OFFSET_
++				, pmlmeinfo->hidden_ssid_mode
++			);
++			pframe += (cur_network->IELength+len_diff);
++			pattrib->pktlen += (cur_network->IELength+len_diff);
++		}
++
++		{
++			u8 *wps_ie;
++			uint wps_ielen;
++			u8 sr = 0;
++			wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
++				pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
++			if (wps_ie && wps_ielen>0) {
++				rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
++			}
++			if (sr != 0)
++				set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
++			else
++				_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
++		}
++
++#ifdef CONFIG_P2P
++		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
++		{
++			u32 len;
++#ifdef CONFIG_IOCTL_CFG80211
++			if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++			{
++				len = pmlmepriv->p2p_beacon_ie_len;
++				if(pmlmepriv->p2p_beacon_ie && len>0)
++					_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
++			}
++			else
++#endif //CONFIG_IOCTL_CFG80211
++			{
++				len = build_beacon_p2p_ie(pwdinfo, pframe);
++			}
++
++			pframe += len;
++			pattrib->pktlen += len;
++#ifdef CONFIG_WFD
++#ifdef CONFIG_IOCTL_CFG80211
++			if(_TRUE == pwdinfo->wfd_info->wfd_enable)
++#endif //CONFIG_IOCTL_CFG80211
++			{
++				len = build_beacon_wfd_ie( pwdinfo, pframe );
++			}
++#ifdef CONFIG_IOCTL_CFG80211
++			else
++			{
++				len = 0;
++				if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
++				{
++					len = pmlmepriv->wfd_beacon_ie_len;
++					_rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
++				}
++			}
++#endif //CONFIG_IOCTL_CFG80211
++			pframe += len;
++			pattrib->pktlen += len;
++#endif //CONFIG_WFD
++		}
++#endif //CONFIG_P2P
++
++		goto _issue_bcn;
++
++	}
++
++	//below for ad-hoc mode
++
++	//timestamp will be inserted by hardware
++	pframe += 8;
++	pattrib->pktlen += 8;
++
++	// beacon interval: 2 bytes
++
++	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
++
++	pframe += 2;
++	pattrib->pktlen += 2;
++
++	// capability info: 2 bytes
++
++	_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
++
++	pframe += 2;
++	pattrib->pktlen += 2;
++
++	// SSID
++	pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
++
++	// supported rates...
++	rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
++	pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
++
++	// DS parameter set
++	pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
++
++	//if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
++	{
++		u8 erpinfo=0;
++		u32 ATIMWindow;
++		// IBSS Parameter Set...
++		//ATIMWindow = cur->Configuration.ATIMWindow;
++		ATIMWindow = 0;
++		pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
++
++		//ERP IE
++		pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
++	}
++
++
++	// EXTERNDED SUPPORTED RATE
++	if (rate_len > 8)
++	{
++		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
++	}
++
++
++	//todo:HT for adhoc
++
++_issue_bcn:
++
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	pmlmepriv->update_bcn = _FALSE;
++
++	_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
++#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++
++	if ((pattrib->pktlen + TXDESC_SIZE) > 512)
++	{
++		DBG_871X("beacon frame too large\n");
++		return;
++	}
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	//DBG_871X("issue bcn_sz=%d\n", pattrib->last_txcmdsz);
++
++	dump_mgntframe(padapter, pmgntframe);
++
++}
++
++void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
++{
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	unsigned char					*mac, *bssid;
++	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	u8 *pwps_ie;
++	uint wps_ielen;
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++#endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX 		*cur_network = &(pmlmeinfo->network);
++	unsigned int	rate_len;
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++#endif //CONFIG_P2P
++
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		DBG_871X("%s, alloc mgnt frame fail\n", __FUNCTION__);
++		return;
++	}
++
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	mac = myid(&(padapter->eeprompriv));
++	bssid = cur_network->MacAddress;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(fctrl, WIFI_PROBERSP);
++
++	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = pattrib->hdrlen;
++	pframe += pattrib->hdrlen;
++
++
++	if(cur_network->IELength>MAX_IE_SZ)
++		return;
++
++#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
++	if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
++	{
++		pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
++
++		//inerset & update wps_probe_resp_ie
++		if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
++		{
++			uint wps_offset, remainder_ielen;
++			u8 *premainder_ie;
++
++			wps_offset = (uint)(pwps_ie - cur_network->IEs);
++
++			premainder_ie = pwps_ie + wps_ielen;
++
++			remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
++
++			_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
++			pframe += wps_offset;
++			pattrib->pktlen += wps_offset;
++
++			wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
++			if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
++			{
++				_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
++				pframe += wps_ielen+2;
++				pattrib->pktlen += wps_ielen+2;
++			}
++
++			if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
++			{
++				_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
++				pframe += remainder_ielen;
++				pattrib->pktlen += remainder_ielen;
++			}
++		}
++		else
++		{
++			_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
++			pframe += cur_network->IELength;
++			pattrib->pktlen += cur_network->IELength;
++		}
++
++		/* retrieve SSID IE from cur_network->Ssid */
++		{
++			u8 *ssid_ie;
++			sint ssid_ielen;
++			sint ssid_ielen_diff;
++			u8 buf[MAX_IE_SZ];
++			u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
++
++			ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
++				(pframe-ies)-_FIXED_IE_LENGTH_);
++
++			ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
++
++			if (ssid_ie &&  cur_network->Ssid.SsidLength) {
++				uint remainder_ielen;
++				u8 *remainder_ie;
++				remainder_ie = ssid_ie+2;
++				remainder_ielen = (pframe-remainder_ie);
++
++				LOG_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
++				if (remainder_ielen > MAX_IE_SZ) {
++					remainder_ielen = MAX_IE_SZ;
++				}
++
++				_rtw_memcpy(buf, remainder_ie, remainder_ielen);
++				_rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
++				*(ssid_ie+1) = cur_network->Ssid.SsidLength;
++				_rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
++
++				pframe += ssid_ielen_diff;
++				pattrib->pktlen += ssid_ielen_diff;
++			}
++		}
++	}
++	else
++#endif
++	{
++
++		//timestamp will be inserted by hardware
++		pframe += 8;
++		pattrib->pktlen += 8;
++
++		// beacon interval: 2 bytes
++
++		_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
++
++		pframe += 2;
++		pattrib->pktlen += 2;
++
++		// capability info: 2 bytes
++
++		_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
++
++		pframe += 2;
++		pattrib->pktlen += 2;
++
++		//below for ad-hoc mode
++
++		// SSID
++		pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
++
++		// supported rates...
++		rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
++
++		// DS parameter set
++		pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
++
++		if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
++		{
++			u8 erpinfo=0;
++			u32 ATIMWindow;
++			// IBSS Parameter Set...
++			//ATIMWindow = cur->Configuration.ATIMWindow;
++			ATIMWindow = 0;
++			pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
++
++			//ERP IE
++			pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
++		}
++
++
++		// EXTERNDED SUPPORTED RATE
++		if (rate_len > 8)
++		{
++			pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
++		}
++
++
++		//todo:HT for adhoc
++
++	}
++
++#ifdef CONFIG_P2P
++	if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) /*&& is_valid_p2p_probereq*/)
++	{
++		u32 len;
++#ifdef CONFIG_IOCTL_CFG80211
++		if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++		{
++			//if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
++			len = pmlmepriv->p2p_go_probe_resp_ie_len;
++			if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
++				_rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
++		}
++		else
++#endif //CONFIG_IOCTL_CFG80211
++		{
++			len = build_probe_resp_p2p_ie(pwdinfo, pframe);
++		}
++
++		pframe += len;
++		pattrib->pktlen += len;
++
++#ifdef CONFIG_WFD
++#ifdef CONFIG_IOCTL_CFG80211
++		if(_TRUE == pwdinfo->wfd_info->wfd_enable)
++#endif //CONFIG_IOCTL_CFG80211
++		{
++			len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
++		}
++#ifdef CONFIG_IOCTL_CFG80211
++		else
++		{
++			len = 0;
++			if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
++			{
++				len = pmlmepriv->wfd_probe_resp_ie_len;
++				_rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
++			}
++		}
++#endif //CONFIG_IOCTL_CFG80211
++		pframe += len;
++		pattrib->pktlen += len;
++#endif //CONFIG_WFD
++
++	}
++#endif //CONFIG_P2P
++
++
++#ifdef CONFIG_AUTO_AP_MODE
++{
++	struct sta_info *psta;
++	struct sta_priv *pstapriv = &padapter->stapriv;
++
++	DBG_871X("(%s)\n", __FUNCTION__);
++
++	//check rc station
++	psta = rtw_get_stainfo(pstapriv, da);
++	if (psta && psta->isrc && psta->pid>0)
++	{
++		u8 RC_OUI[4]={0x00,0xE0,0x4C,0x0A};
++		u8 RC_INFO[14] = {0};
++		//EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2]
++		u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
++
++		DBG_871X("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
++			psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
++
++		//append vendor specific ie
++		_rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
++		_rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
++		_rtw_memcpy(&RC_INFO[10], (u8*)&psta->pid, 2);
++		_rtw_memcpy(&RC_INFO[12], (u8*)&cu_ch, 2);
++
++		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
++	}
++}
++#endif //CONFIG_AUTO_AP_MODE
++
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++
++}
++
++int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, int wait_ack)
++{
++	int ret = _FAIL;
++	struct xmit_frame		*pmgntframe;
++	struct pkt_attrib		*pattrib;
++	unsigned char			*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short		*fctrl;
++	unsigned char			*mac;
++	unsigned char			bssrate[NumRates];
++	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	int	bssrate_len = 0;
++	u8	bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n"));
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		goto exit;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	mac = myid(&(padapter->eeprompriv));
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	if (da)
++	{
++		//	unicast probe request frame
++		_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
++	}
++	else
++	{
++		//	broadcast probe request frame
++		_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
++	}
++
++	_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_PROBEREQ);
++
++	pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
++
++	if(pssid)
++		pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
++	else
++		pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
++
++	get_rate_set(padapter, bssrate, &bssrate_len);
++
++	if (bssrate_len > 8)
++	{
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
++		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
++	}
++	else
++	{
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
++	}
++
++#if 0
++	//add wps_ie for wps2.0
++	if(pmlmepriv->probereq_wpsie_len>0 && pmlmepriv->probereq_wpsie_len<MAX_WPS_IE_LEN)
++	{
++		_rtw_memcpy(pframe, pmlmepriv->probereq_wpsie, pmlmepriv->probereq_wpsie_len);
++		pframe += pmlmepriv->probereq_wpsie_len;
++		pattrib->pktlen += pmlmepriv->probereq_wpsie_len;
++		//pmlmepriv->probereq_wpsie_len = 0 ;//reset to zero
++	}
++#else
++	//add wps_ie for wps2.0
++	if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
++	{
++		_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
++		pframe += pmlmepriv->wps_probe_req_ie_len;
++		pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
++		//pmlmepriv->wps_probe_req_ie_len = 0 ;//reset to zero
++	}
++#endif
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
++
++	if (wait_ack) {
++		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
++	} else {
++		dump_mgntframe(padapter, pmgntframe);
++		ret = _SUCCESS;
++	}
++
++exit:
++	return ret;
++}
++
++inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
++{
++	_issue_probereq(padapter, pssid, da, _FALSE);
++}
++
++int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da,
++	int try_cnt, int wait_ms)
++{
++	int ret;
++	int i = 0;
++	u32 start = rtw_get_current_time();
++
++	do
++	{
++		ret = _issue_probereq(padapter, pssid, da, wait_ms>0?_TRUE:_FALSE);
++
++		i++;
++
++		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
++			break;
++
++		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
++			rtw_msleep_os(wait_ms);
++
++	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
++
++	if (ret != _FAIL) {
++		ret = _SUCCESS;
++		#ifndef DBG_XMIT_ACK
++		goto exit;
++		#endif
++	}
++
++	if (try_cnt && wait_ms) {
++		if (da)
++			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++		else
++			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++	}
++exit:
++	return ret;
++}
++
++// if psta == NULL, indiate we are station(client) now...
++void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
++{
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	unsigned int					val32;
++	unsigned short				val16;
++	int use_shared_key = 0;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_AUTH);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++
++	if(psta)// for AP mode
++	{
++#ifdef CONFIG_NATIVEAP_MLME
++
++		_rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
++
++
++		// setting auth algo number
++		val16 = (u16)psta->authalg;
++
++		if(status != _STATS_SUCCESSFUL_)
++			val16 = 0;
++
++		if (val16)	{
++			val16 = cpu_to_le16(val16);
++			use_shared_key = 1;
++		}
++
++		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
++
++		// setting auth seq number
++		val16 =(u16)psta->auth_seq;
++		val16 = cpu_to_le16(val16);
++		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
++
++		// setting status code...
++		val16 = status;
++		val16 = cpu_to_le16(val16);
++		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
++
++		// added challenging text...
++		if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
++		{
++			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
++		}
++#endif
++	}
++	else
++	{
++		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
++		_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
++
++		// setting auth algo number
++		val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;// 0:OPEN System, 1:Shared key
++		if (val16)	{
++			val16 = cpu_to_le16(val16);
++			use_shared_key = 1;
++		}
++		//DBG_871X("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq);
++
++		//setting IV for auth seq #3
++		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
++		{
++			//DBG_871X("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index);
++			val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
++			val32 = cpu_to_le32(val32);
++			pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
++
++			pattrib->iv_len = 4;
++		}
++
++		pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
++
++		// setting auth seq number
++		val16 = pmlmeinfo->auth_seq;
++		val16 = cpu_to_le16(val16);
++		pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
++
++
++		// setting status code...
++		val16 = status;
++		val16 = cpu_to_le16(val16);
++		pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
++
++		// then checking to see if sending challenging text...
++		if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
++		{
++			pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
++
++			SetPrivacy(fctrl);
++
++			pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++			pattrib->encrypt = _WEP40_;
++
++			pattrib->icv_len = 4;
++
++			pattrib->pktlen += pattrib->icv_len;
++
++		}
++
++	}
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
++
++	dump_mgntframe(padapter, pmgntframe);
++
++	return;
++}
++
++
++void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
++{
++#ifdef CONFIG_AP_MODE
++	struct xmit_frame	*pmgntframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	struct pkt_attrib *pattrib;
++	unsigned char	*pbuf, *pframe;
++	unsigned short val;
++	unsigned short *fctrl;
++	struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
++	u8 *ie = pnetwork->IEs;
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++#endif //CONFIG_P2P
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
++	_rtw_memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
++		SetFrameSubType(pwlanhdr, pkt_type);
++	else
++		return;
++
++	pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen += pattrib->hdrlen;
++	pframe += pattrib->hdrlen;
++
++	//capability
++	val = *(unsigned short *)rtw_get_capability_from_ie(ie);
++
++	pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
++
++	status = cpu_to_le16(status);
++	pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen));
++
++	val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
++	pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
++
++	if (pstat->bssratelen <= 8)
++	{
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
++	}
++	else
++	{
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
++		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
++	}
++
++#ifdef CONFIG_80211N_HT
++	if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
++	{
++		uint ie_len=0;
++
++		//FILL HT CAP INFO IE
++		//p = hostapd_eid_ht_capabilities_info(hapd, p);
++		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
++		if(pbuf && ie_len>0)
++		{
++			_rtw_memcpy(pframe, pbuf, ie_len+2);
++			pframe += (ie_len+2);
++			pattrib->pktlen +=(ie_len+2);
++		}
++
++		//FILL HT ADD INFO IE
++		//p = hostapd_eid_ht_operation(hapd, p);
++		pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
++		if(pbuf && ie_len>0)
++		{
++			_rtw_memcpy(pframe, pbuf, ie_len+2);
++			pframe += (ie_len+2);
++			pattrib->pktlen +=(ie_len+2);
++		}
++
++	}
++#endif
++
++	//FILL WMM IE
++	if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
++	{
++		uint ie_len=0;
++		unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
++
++		for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
++		{
++			pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
++			if(pbuf && _rtw_memcmp(pbuf+2, WMM_PARA_IE, 6))
++			{
++				_rtw_memcpy(pframe, pbuf, ie_len+2);
++				pframe += (ie_len+2);
++				pattrib->pktlen +=(ie_len+2);
++
++				break;
++			}
++
++			if ((pbuf == NULL) || (ie_len == 0))
++			{
++				break;
++			}
++		}
++
++	}
++
++
++	if (pmlmeinfo->assoc_AP_vendor == realtekAP)
++	{
++		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
++	}
++
++	//add WPS IE ie for wps 2.0
++	if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
++	{
++		_rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
++
++		pframe += pmlmepriv->wps_assoc_resp_ie_len;
++		pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
++	}
++
++#ifdef CONFIG_P2P
++	if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
++	{
++		if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
++		{
++			u32 len;
++
++			len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
++
++			pframe += len;
++			pattrib->pktlen += len;
++		}
++	}
++#ifdef CONFIG_WFD
++	if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
++#ifdef CONFIG_IOCTL_CFG80211
++		&& (_TRUE == pwdinfo->wfd_info->wfd_enable)
++#endif //CONFIG_IOCTL_CFG80211
++	)
++	{
++		wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
++		pframe += wfdielen;
++		pattrib->pktlen += wfdielen;
++	}
++#endif //CONFIG_WFD
++#endif //CONFIG_P2P
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++#endif
++}
++
++void issue_assocreq(_adapter *padapter)
++{
++	int ret = _FAIL;
++	struct xmit_frame				*pmgntframe;
++	struct pkt_attrib				*pattrib;
++	unsigned char					*pframe, *p;
++	struct rtw_ieee80211_hdr			*pwlanhdr;
++	unsigned short				*fctrl;
++	unsigned short				val16;
++	unsigned int					i, j, ie_len, index=0;
++	unsigned char					rf_type, bssrate[NumRates], sta_bssrate[NumRates];
++	PNDIS_802_11_VARIABLE_IEs	pIE;
++	struct registry_priv	*pregpriv = &padapter->registrypriv;
++	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	int	bssrate_len = 0, sta_bssrate_len = 0;
++	u8	cbw40_enable = 0;
++#ifdef CONFIG_P2P
++	struct wifidirect_info	*pwdinfo = &(padapter->wdinfo);
++	u8					p2pie[ 255 ] = { 0x00 };
++	u16					p2pielen = 0;
++#ifdef CONFIG_WFD
++	u32					wfdielen = 0;
++#endif //CONFIG_WFD
++#endif //CONFIG_P2P
++
++#ifdef CONFIG_DFS
++	u16	cap;
++	u8 pow_cap_ele[2] = { 0x00 };
++	u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2;	//For supported channel
++#endif //CONFIG_DFS
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++		goto exit;
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ASSOCREQ);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	//caps
++
++#ifdef CONFIG_DFS
++	_rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
++	if(pmlmeext->cur_channel > 14)
++		cap |= BIT(8); //Spectrum Mgmt. Enabled
++	_rtw_memcpy(pframe, &cap, 2);
++#else
++	_rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
++#endif //CONFIG_DFS
++
++	pframe += 2;
++	pattrib->pktlen += 2;
++
++	//listen interval
++	//todo: listen interval for power saving
++	val16 = cpu_to_le16(3);
++	_rtw_memcpy(pframe ,(unsigned char *)&val16, 2);
++	pframe += 2;
++	pattrib->pktlen += 2;
++
++	//SSID
++	pframe = rtw_set_ie(pframe, _SSID_IE_,  pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
++
++	//supported rate & extended supported rate
++
++#if 1	// Check if the AP's supported rates are also supported by STA.
++	get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
++	//DBG_871X("sta_bssrate_len=%d\n", sta_bssrate_len);
++
++	if(pmlmeext->cur_channel == 14)// for JAPAN, channel 14 can only uses B Mode(CCK)
++	{
++		sta_bssrate_len = 4;
++	}
++
++
++	//for (i = 0; i < sta_bssrate_len; i++) {
++	//	DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]);
++	//}
++
++	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
++		if (pmlmeinfo->network.SupportedRates[i] == 0) break;
++		DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
++	}
++
++
++	for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
++		if (pmlmeinfo->network.SupportedRates[i] == 0) break;
++
++
++		// Check if the AP's supported rates are also supported by STA.
++		for (j=0; j < sta_bssrate_len; j++) {
++			 // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
++			if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
++					== (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
++				//DBG_871X("match i = %d, j=%d\n", i, j);
++				break;
++			} else {
++				//DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK));
++			}
++		}
++
++		if (j == sta_bssrate_len) {
++			// the rate is not supported by STA
++			DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
++		} else {
++			// the rate is supported by STA
++			bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
++		}
++	}
++
++	bssrate_len = index;
++	DBG_871X("bssrate_len = %d\n", bssrate_len);
++
++#else	// Check if the AP's supported rates are also supported by STA.
++#if 0
++	get_rate_set(padapter, bssrate, &bssrate_len);
++#else
++	for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
++		if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0) break;
++
++		if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) // Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP
++			break;
++
++		bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
++	}
++#endif
++#endif	// Check if the AP's supported rates are also supported by STA.
++
++	if (bssrate_len == 0) {
++		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
++		rtw_free_xmitframe(pxmitpriv, pmgntframe);
++		goto exit; //don't connect to AP if no joint supported rate
++	}
++
++
++	if (bssrate_len > 8)
++	{
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
++		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
++	}
++	else
++	{
++		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
++	}
++
++#ifdef CONFIG_DFS
++	if(pmlmeext->cur_channel > 14)
++	{
++		pow_cap_ele[0] = 13;	// Minimum transmit power capability
++		pow_cap_ele[1] = 21;	// Maximum transmit power capability
++		pframe = rtw_set_ie(pframe, _POW_CAP_IE_, 2, pow_cap_ele, &(pattrib->pktlen));
++
++		//supported channels
++		do{
++			if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
++			{
++				sup_ch[0] = 1;	//First channel number
++				sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;	//Number of channel
++			}
++			else
++			{
++				sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
++				sup_ch[idx_5g++] = 1;
++			}
++			sup_ch_idx++;
++		}
++		while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
++		pframe = rtw_set_ie(pframe, _SUPPORTED_CH_IE_, idx_5g, sup_ch, &(pattrib->pktlen));
++	}
++#endif //CONFIG_DFS
++
++	//RSN
++	p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs)));
++	if (p != NULL)
++	{
++		pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen));
++	}
++
++#ifdef CONFIG_80211N_HT
++	//HT caps
++	if(padapter->mlmepriv.htpriv.ht_option==_TRUE)
++	{
++		p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs)));
++		if ((p != NULL) && (!(is_ap_in_tkip(padapter))))
++		{
++			_rtw_memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element));
++
++			//to disable 40M Hz support while gd_bw_40MHz_en = 0
++			if( pmlmeext->cur_channel > 14)
++			{
++				if(pregpriv->cbw40_enable & BIT(1) )
++					cbw40_enable=1;
++			}
++			else
++				if(pregpriv->cbw40_enable & BIT(0) )
++					cbw40_enable=1;
++
++			if (cbw40_enable == 0)
++			{
++				pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
++			}
++			else
++			{
++				pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
++			}
++
++			//todo: disable SM power save mode
++			pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= 0x000c;
++
++			rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
++			//switch (pregpriv->rf_config)
++			switch(rf_type)
++			{
++				case RF_1T1R:
++
++					if(pregpriv->rx_stbc)
++						pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
++
++					_rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
++					break;
++
++				case RF_2T2R:
++				case RF_1T2R:
++				default:
++
++
++					if(pregpriv->special_rf_path)
++					{
++						if(pregpriv->rx_stbc)
++							pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
++						_rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
++						break;
++					}
++
++					if((pregpriv->rx_stbc == 0x3) ||//enable for 2.4/5 GHz
++						((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || //enable for 2.4GHz
++						((pmlmeext->cur_wireless_mode & WIRELESS_11_5N) && (pregpriv->rx_stbc == 0x2)) || //enable for 5GHz
++						(pregpriv->wifi_spec==1))
++					{
++						DBG_871X("declare supporting RX STBC\n");
++						pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);//RX STBC two spatial stream
++					}
++					#ifdef CONFIG_DISABLE_MCS13TO15
++					if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && (pregpriv->wifi_spec!=1))
++						_rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R_MCS13TO15_OFF, 16);
++					else
++					_rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
++					#else //CONFIG_DISABLE_MCS13TO15
++					_rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
++					#endif //CONFIG_DISABLE_MCS13TO15
++					break;
++			}
++#ifdef RTL8192C_RECONFIG_TO_1T1R
++			{
++				if(pregpriv->rx_stbc)
++					pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);//RX STBC One spatial stream
++
++				_rtw_memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
++			}
++#endif
++			pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
++			pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
++
++		}
++	}
++#endif
++
++	//vendor specific IE, such as WPA, WMM, WPS
++	for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
++	{
++		pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
++
++		switch (pIE->ElementID)
++		{
++			case _VENDOR_SPECIFIC_IE_:
++				if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
++						(_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
++						(_rtw_memcmp(pIE->data, WPS_OUI, 4)))
++				{
++					if(!padapter->registrypriv.wifi_spec)
++					{
++						//Commented by Kurt 20110629
++						//In some older APs, WPS handshake
++						//would be fail if we append vender extensions informations to AP
++						if(_rtw_memcmp(pIE->data, WPS_OUI, 4)){
++							pIE->Length=14;
++						}
++					}
++					pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen));
++				}
++				break;
++
++			default:
++				break;
++		}
++
++		i += (pIE->Length + 2);
++	}
++
++	if (pmlmeinfo->assoc_AP_vendor == realtekAP)
++	{
++		pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
++	}
++
++#ifdef CONFIG_P2P
++
++#ifdef CONFIG_IOCTL_CFG80211
++	if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
++	{
++		if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
++		{
++			_rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
++			pframe += pmlmepriv->p2p_assoc_req_ie_len;
++			pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
++		}
++	}
++	else
++#endif //CONFIG_IOCTL_CFG80211
++	{
++		if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
++		{
++			//	Should add the P2P IE in the association request frame.
++			//	P2P OUI
++
++			p2pielen = 0;
++			p2pie[ p2pielen++ ] = 0x50;
++			p2pie[ p2pielen++ ] = 0x6F;
++			p2pie[ p2pielen++ ] = 0x9A;
++			p2pie[ p2pielen++ ] = 0x09;	//	WFA P2P v1.0
++
++			//	Commented by Albert 20101109
++			//	According to the P2P Specification, the association request frame should contain 3 P2P attributes
++			//	1. P2P Capability
++			//	2. Extended Listen Timing
++			//	3. Device Info
++			//	Commented by Albert 20110516
++			//	4. P2P Interface
++
++			//	P2P Capability
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
++			p2pielen += 2;
++
++			//	Value:
++			//	Device Capability Bitmap, 1 byte
++			p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
++
++			//	Group Capability Bitmap, 1 byte
++			if ( pwdinfo->persistent_supported )
++				p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
++			else
++				p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
++
++			//	Extended Listen Timing
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
++			p2pielen += 2;
++
++			//	Value:
++			//	Availability Period
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
++			p2pielen += 2;
++
++			//	Availability Interval
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
++			p2pielen += 2;
++
++			//	Device Info
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
++
++			//	Length:
++			//	21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
++			//	+ NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
++			p2pielen += 2;
++
++			//	Value:
++			//	P2P Device Address
++			_rtw_memcpy( p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
++			p2pielen += ETH_ALEN;
++
++			//	Config Method
++			//	This field should be big endian. Noted by P2P specification.
++			if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
++				( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
++			{
++				*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
++			}
++			else
++			{
++				*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
++			}
++
++			p2pielen += 2;
++
++			//	Primary Device Type
++			//	Category ID
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
++			p2pielen += 2;
++
++			//	OUI
++			*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
++			p2pielen += 4;
++
++			//	Sub Category ID
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
++			p2pielen += 2;
++
++			//	Number of Secondary Device Types
++			p2pie[ p2pielen++ ] = 0x00;	//	No Secondary Device Type List
++
++			//	Device Name
++			//	Type:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
++			p2pielen += 2;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
++			p2pielen += 2;
++
++			//	Value:
++			_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
++			p2pielen += pwdinfo->device_name_len;
++
++			//	P2P Interface
++			//	Type:
++			p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
++
++			//	Length:
++			*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
++			p2pielen += 2;
++
++			//	Value:
++			_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );	//	P2P Device Address
++			p2pielen += ETH_ALEN;
++
++			p2pie[ p2pielen++ ] = 1;	//	P2P Interface Address Count
++
++			_rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );	//	P2P Interface Address List
++			p2pielen += ETH_ALEN;
++
++			pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
++
++#ifdef CONFIG_WFD
++			//wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
++			//pframe += wfdielen;
++			//pattrib->pktlen += wfdielen;
++#endif //CONFIG_WFD
++		}
++	}
++
++#endif //CONFIG_P2P
++
++#ifdef CONFIG_WFD
++#ifdef CONFIG_IOCTL_CFG80211
++	if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
++#endif //CONFIG_IOCTL_CFG80211
++	{
++		wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
++		pframe += wfdielen;
++		pattrib->pktlen += wfdielen;
++	}
++#ifdef CONFIG_IOCTL_CFG80211
++	else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
++	{
++		//WFD IE
++		_rtw_memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
++		pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
++		pframe += pmlmepriv->wfd_assoc_req_ie_len;
++	}
++#endif //CONFIG_IOCTL_CFG80211
++#endif //CONFIG_WFD
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++	dump_mgntframe(padapter, pmgntframe);
++
++	ret = _SUCCESS;
++
++exit:
++	if (ret == _SUCCESS)
++		rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
++	else
++		rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
++
++	return;
++}
++
++//when wait_ack is ture, this function shoule be called at process context
++static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
++{
++	int ret = _FAIL;
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv	*pxmitpriv;
++	struct mlme_ext_priv	*pmlmeext;
++	struct mlme_ext_info	*pmlmeinfo;
++
++	//DBG_871X("%s:%d\n", __FUNCTION__, power_mode);
++
++	if(!padapter)
++		goto exit;
++
++	pxmitpriv = &(padapter->xmitpriv);
++	pmlmeext = &(padapter->mlmeextpriv);
++	pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		goto exit;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++	pattrib->retry_ctrl = _FALSE;
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
++	{
++		SetFrDs(fctrl);
++	}
++	else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
++	{
++		SetToDs(fctrl);
++	}
++
++	if (power_mode)
++	{
++		SetPwrMgt(fctrl);
++	}
++
++	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_DATA_NULL);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	if(wait_ack)
++	{
++		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
++	}
++	else
++	{
++		dump_mgntframe(padapter, pmgntframe);
++		ret = _SUCCESS;
++	}
++
++exit:
++	return ret;
++}
++
++
++//when wait_ms >0 , this function shoule be called at process context
++//da == NULL for station mode
++int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
++{
++	int ret;
++	int i = 0;
++	u32 start = rtw_get_current_time();
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	/* da == NULL, assum it's null data for sta to ap*/
++	if (da == NULL)
++		da = get_my_bssid(&(pmlmeinfo->network));
++
++	do
++	{
++		ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
++
++		i++;
++
++		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
++			break;
++
++		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
++			rtw_msleep_os(wait_ms);
++
++	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
++
++	if (ret != _FAIL) {
++		ret = _SUCCESS;
++		#ifndef DBG_XMIT_ACK
++		goto exit;
++		#endif
++	}
++
++	if (try_cnt && wait_ms) {
++		if (da)
++			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++		else
++			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++	}
++exit:
++	return ret;
++}
++
++//when wait_ack is ture, this function shoule be called at process context
++static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
++{
++	int ret = _FAIL;
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl, *qc;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		goto exit;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	pattrib->hdrlen +=2;
++	pattrib->qos_en = _TRUE;
++	pattrib->eosp = 1;
++	pattrib->ack_policy = 0;
++	pattrib->mdata = 0;
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
++	{
++		SetFrDs(fctrl);
++	}
++	else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
++	{
++		SetToDs(fctrl);
++	}
++
++	if(pattrib->mdata)
++		SetMData(fctrl);
++
++	qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
++
++	SetPriority(qc, tid);
++
++	SetEOSP(qc, pattrib->eosp);
++
++	SetAckpolicy(qc, pattrib->ack_policy);
++
++	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	if(wait_ack)
++	{
++		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
++	}
++	else
++	{
++		dump_mgntframe(padapter, pmgntframe);
++		ret = _SUCCESS;
++	}
++
++exit:
++	return ret;
++}
++
++//when wait_ms >0 , this function shoule be called at process context
++//da == NULL for station mode
++int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
++{
++	int ret;
++	int i = 0;
++	u32 start = rtw_get_current_time();
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	/* da == NULL, assum it's null data for sta to ap*/
++	if (da == NULL)
++		da = get_my_bssid(&(pmlmeinfo->network));
++
++	do
++	{
++		ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
++
++		i++;
++
++		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
++			break;
++
++		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
++			rtw_msleep_os(wait_ms);
++
++	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
++
++	if (ret != _FAIL) {
++		ret = _SUCCESS;
++		#ifndef DBG_XMIT_ACK
++		goto exit;
++		#endif
++	}
++
++	if (try_cnt && wait_ms) {
++		if (da)
++			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++		else
++			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++	}
++exit:
++	return ret;
++}
++
++static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
++{
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short				*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	int ret = _FAIL;
++#ifdef CONFIG_P2P
++	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
++#endif //CONFIG_P2P
++
++	//DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
++
++#ifdef CONFIG_P2P
++	if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
++	{
++		_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
++		_set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
++	}
++#endif //CONFIG_P2P
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		goto exit;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++	pattrib->retry_ctrl = _FALSE;
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_DEAUTH);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	reason = cpu_to_le16(reason);
++	pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++
++	if(wait_ack)
++	{
++		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
++	}
++	else
++	{
++		dump_mgntframe(padapter, pmgntframe);
++		ret = _SUCCESS;
++	}
++
++exit:
++	return ret;
++}
++
++int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
++{
++	DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
++	return _issue_deauth(padapter, da, reason, _FALSE);
++}
++
++int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
++	int wait_ms)
++{
++	int ret;
++	int i = 0;
++	u32 start = rtw_get_current_time();
++
++	do
++	{
++		ret = _issue_deauth(padapter, da, reason, wait_ms>0?_TRUE:_FALSE);
++
++		i++;
++
++		if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
++			break;
++
++		if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
++			rtw_msleep_os(wait_ms);
++
++	}while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
++
++	if (ret != _FAIL) {
++		ret = _SUCCESS;
++		#ifndef DBG_XMIT_ACK
++		goto exit;
++		#endif
++	}
++
++	if (try_cnt && wait_ms) {
++		if (da)
++			DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++		else
++			DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
++				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
++				ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
++	}
++exit:
++	return ret;
++}
++
++void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
++{
++	_irqL	irqL;
++	_list		*plist, *phead;
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char				*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short			*fctrl;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++
++	DBG_871X(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
++		FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++		return;
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */
++	_rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	/* category, action */
++	{
++		u8 category, action;
++		category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
++		action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
++
++		pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++		pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++	}
++
++	pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
++	pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
++		hal_ch_offset_to_secondary_ch_offset(ch_offset));
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++}
++
++#ifdef CONFIG_IEEE80211W
++void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid)
++{
++	u8	category = RTW_WLAN_CATEGORY_SA_QUERY;
++	u16	reason_code;
++	struct xmit_frame		*pmgntframe;
++	struct pkt_attrib		*pattrib;
++	u8					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	u16					*fctrl;
++	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct sta_info		*psta;
++	struct sta_priv		*pstapriv = &padapter->stapriv;
++	struct registry_priv	 	*pregpriv = &padapter->registrypriv;
++
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	if(raddr)
++		_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	else
++		_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
++	pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
++
++	switch (action)
++	{
++		case 0: //SA Query req
++			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
++			pmlmeext->sa_query_seq++;
++			//send sa query request to AP, AP should reply sa query response in 1 second
++			set_sa_query_timer(pmlmeext, 1000);
++			break;
++
++		case 1: //SA Query rsp
++			tid = cpu_to_le16(tid);
++			pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
++			break;
++		default:
++			break;
++	}
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++}
++#endif //CONFIG_IEEE80211W
++
++void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
++{
++	u8	category = RTW_WLAN_CATEGORY_BACK;
++	u16	start_seq;
++	u16	BA_para_set;
++	u16	reason_code;
++	u16	BA_timeout_value;
++	u16	BA_starting_seqctrl;
++	struct xmit_frame		*pmgntframe;
++	struct pkt_attrib		*pattrib;
++	u8					*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	u16					*fctrl;
++	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct sta_info		*psta;
++	struct sta_priv		*pstapriv = &padapter->stapriv;
++	struct registry_priv	 	*pregpriv = &padapter->registrypriv;
++
++
++	DBG_871X("%s, category=%d, action=%d, status=%d\n", __FUNCTION__, category, action, status);
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	//_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++
++      status = cpu_to_le16(status);
++
++
++	if (category == 3)
++	{
++		switch (action)
++		{
++			case 0: //ADDBA req
++				do {
++					pmlmeinfo->dialogToken++;
++				} while (pmlmeinfo->dialogToken == 0);
++				pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
++
++				BA_para_set = (0x1002 | ((status & 0xf) << 2)); //immediate ack & 64 buffer size
++				//sys_mib.BA_para_set = 0x0802; //immediate ack & 32 buffer size
++				BA_para_set = cpu_to_le16(BA_para_set);
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
++
++				//BA_timeout_value = 0xffff;//max: 65535 TUs(~ 65 ms)
++				BA_timeout_value = 5000;//~ 5ms
++				BA_timeout_value = cpu_to_le16(BA_timeout_value);
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
++
++				//if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
++				if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
++				{
++					start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
++
++					DBG_871X("BA_starting_seqctrl = %d for TID=%d\n", start_seq, status & 0x07);
++
++					psta->BA_starting_seqctrl[status & 0x07] = start_seq;
++
++					BA_starting_seqctrl = start_seq << 4;
++				}
++
++				BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
++				break;
++
++			case 1: //ADDBA rsp
++				pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
++
++				//BA_para_set = cpu_to_le16((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
++				BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); //64 buffer size
++
++				if(pregpriv->ampdu_amsdu==0)//disabled
++					BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
++				else if(pregpriv->ampdu_amsdu==1)//enabled
++					BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
++				else //auto
++					BA_para_set = cpu_to_le16(BA_para_set);
++
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
++				break;
++			case 2://DELBA
++				BA_para_set = (status & 0x1F) << 3;
++				BA_para_set = cpu_to_le16(BA_para_set);
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
++
++				reason_code = 37;//Requested from peer STA as it does not want to use the mechanism
++				reason_code = cpu_to_le16(reason_code);
++				pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(reason_code)), &(pattrib->pktlen));
++				break;
++			default:
++				break;
++		}
++	}
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++}
++
++static void issue_action_BSSCoexistPacket(_adapter *padapter)
++{
++	_irqL	irqL;
++	_list		*plist, *phead;
++	unsigned char category, action;
++	struct xmit_frame			*pmgntframe;
++	struct pkt_attrib			*pattrib;
++	unsigned char				*pframe;
++	struct rtw_ieee80211_hdr	*pwlanhdr;
++	unsigned short			*fctrl;
++	struct	wlan_network	*pnetwork = NULL;
++	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
++	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	_queue		*queue	= &(pmlmepriv->scanned_queue);
++	u8 InfoContent[16] = {0};
++	u8 ICS[8][15];
++
++	if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
++		return;
++
++	if(_TRUE == pmlmeinfo->bwmode_updated)
++		return;
++
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++
++	category = RTW_WLAN_CATEGORY_PUBLIC;
++	action = ACT_PUBLIC_BSSCOEXIST;
++
++	if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
++	{
++		return;
++	}
++
++	//update attribute
++	pattrib = &pmgntframe->attrib;
++	update_mgntframe_attrib(padapter, pattrib);
++
++	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
++
++	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
++	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
++
++	fctrl = &(pwlanhdr->frame_ctl);
++	*(fctrl) = 0;
++
++	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
++	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
++
++	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
++	pmlmeext->mgnt_seq++;
++	SetFrameSubType(pframe, WIFI_ACTION);
++
++	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
++	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
++	pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
++
++
++	//
++	if(pmlmepriv->num_FortyMHzIntolerant>0)
++	{
++		u8 iedata=0;
++
++		iedata |= BIT(2);//20 MHz BSS Width Request
++
++		pframe = rtw_set_ie(pframe, EID_BSSCoexistence,  1, &iedata, &(pattrib->pktlen));
++
++	}
++
++
++	//
++	_rtw_memset(ICS, 0, sizeof(ICS));
++	if(pmlmepriv->num_sta_no_ht>0)
++	{
++		int i;
++
++		_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++		phead = get_list_head(queue);
++		plist = get_next(phead);
++
++		while(1)
++		{
++			int len;
++			u8 *p;
++			WLAN_BSSID_EX *pbss_network;
++
++			if (rtw_end_of_queue_search(phead,plist)== _TRUE)
++				break;
++
++			pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
++
++			plist = get_next(plist);
++
++			pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
++
++			p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
++			if((p==NULL) || (len==0))//non-HT
++			{
++				if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
++					continue;
++
++				ICS[0][pbss_network->Configuration.DSConfig]=1;
++
++				if(ICS[0][0] == 0)
++					ICS[0][0] = 1;
++			}
++
++		}
++
++		_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
++
++
++		for(i= 0;i<8;i++)
++		{
++			if(ICS[i][0] == 1)
++			{
++				int j, k = 0;
++
++				InfoContent[k] = i;
++				//SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i);
++				k++;
++
++				for(j=1;j<=14;j++)
++				{
++					if(ICS[i][j]==1)
++					{
++						if(k<16)
++						{
++							InfoContent[k] = j; //channel number
++							//SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j);
++							k++;
++						}
++					}
++				}
++
++				pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
++
++			}
++
++		}
++
++
++	}
++
++
++	pattrib->last_txcmdsz = pattrib->pktlen;
++
++	dump_mgntframe(padapter, pmgntframe);
++
++}
++
++unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
++{
++	struct sta_priv *pstapriv = &padapter->stapriv;
++	struct sta_info *psta = NULL;
++	//struct recv_reorder_ctrl *preorder_ctrl;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u16 tid;
++
++	if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
++		if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
++			return _SUCCESS;
++
++	psta = rtw_get_stainfo(pstapriv, addr);
++	if(psta==NULL)
++		return _SUCCESS;
++
++	//DBG_871X("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR");
++
++	if(initiator==0) // recipient
++	{
++		for(tid = 0;tid<MAXTID;tid++)
++		{
++			if(psta->recvreorder_ctrl[tid].enable == _TRUE)
++			{
++				DBG_871X("rx agg disable tid(%d)\n",tid);
++				issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
++				psta->recvreorder_ctrl[tid].enable = _FALSE;
++				psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
++				#ifdef DBG_RX_SEQ
++				DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
++					psta->recvreorder_ctrl[tid].indicate_seq);
++				#endif
++			}
++		}
++	}
++	else if(initiator == 1)// originator
++	{
++		//DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
++		for(tid = 0;tid<MAXTID;tid++)
++		{
++			if(psta->htpriv.agg_enable_bitmap & BIT(tid))
++			{
++				DBG_871X("tx agg disable tid(%d)\n",tid);
++				issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F) );
++				psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
++				psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
++
++			}
++		}
++	}
++
++	return _SUCCESS;
++
++}
++
++unsigned int send_beacon(_adapter *padapter)
++{
++	u8	bxmitok = _FALSE;
++	int	issue=0;
++	int poll = 0;
++//#ifdef CONFIG_CONCURRENT_MODE
++	//struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
++	//struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	//_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
++	//struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
++//#endif
++
++#ifdef CONFIG_PCI_HCI
++
++	//DBG_871X("%s\n", __FUNCTION__);
++
++	issue_beacon(padapter);
++
++	return _SUCCESS;
++
++#endif
++
++#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
++	u32 start = rtw_get_current_time();
++
++	rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
++	do{
++		issue_beacon(padapter);
++		issue++;
++		do {
++			rtw_yield_os();
++			rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
++			poll++;
++		}while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
++
++	}while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
++
++	if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
++	{
++		return _FAIL;
++	}
++	if(_FALSE == bxmitok)
++	{
++		DBG_871X("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
++		return _FAIL;
++	}
++	else
++	{
++		u32 passing_time = rtw_get_passing_time_ms(start);
++
++		if(passing_time > 100 || issue > 3)
++			DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
++		//else
++		//	DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
++
++		return _SUCCESS;
++	}
++
++#endif
++
++}
++
++/****************************************************************************
++
++Following are some utitity fuctions for WiFi MLME
++
++*****************************************************************************/
++
++BOOLEAN IsLegal5GChannel(
++	IN PADAPTER			Adapter,
++	IN u8			channel)
++{
++
++	int i=0;
++	u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
++		60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
++		124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
++		161,163,165};
++	for(i=0;i<sizeof(Channel_5G);i++)
++		if(channel == Channel_5G[i])
++			return _TRUE;
++	return _FALSE;
++}
++
++void site_survey(_adapter *padapter)
++{
++	unsigned char		survey_channel = 0, val8;
++	RT_SCAN_TYPE	ScanType = SCAN_PASSIVE;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	u32 initialgain = 0;
++	u8 restore_initial_gain = 1;
++
++#ifdef CONFIG_P2P
++
++#ifdef CONFIG_CONCURRENT_MODE
++
++#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++	u8 stay_buddy_ch = 0;
++#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
++	struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
++
++#endif //CONFIG_CONCURRENT_MODE
++	struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
++	static unsigned char  prev_survey_channel = 0;
++	static unsigned int p2p_scan_count = 0;
++
++
++	if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
++	{
++		if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
++		{
++			survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
++		}
++		else
++		{
++			survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
++		}
++		ScanType = SCAN_ACTIVE;
++	}
++	else if(rtw_p2p_findphase_ex_is_social(pwdinfo))
++	{
++		//	Commented by Albert 2011/06/03
++		//	The driver is in the find phase, it should go through the social channel.
++		int ch_set_idx;
++		survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
++		ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
++		if (ch_set_idx >= 0)
++			ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
++		else
++			ScanType = SCAN_ACTIVE;
++	}
++	else
++#endif //CONFIG_P2P
++	{
++		struct rtw_ieee80211_channel *ch;
++		if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
++			ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
++			survey_channel = ch->hw_value;
++			ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
++		}
++	}
++
++	if (0)
++	DBG_871X(FUNC_ADPT_FMT" ch:%u(cnt:%u,idx:%d) at %dms, %c%c%c\n"
++		, FUNC_ADPT_ARG(padapter)
++		, survey_channel
++		, pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx
++		, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
++		, ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
++		, pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
++	);
++
++	if(survey_channel != 0)
++	{
++		//PAUSE 4-AC Queue when site_survey
++		//rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
++		//val8 |= 0x0f;
++		//rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
++#ifdef CONFIG_CONCURRENT_MODE
++#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++		if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
++		{
++			if( pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH )
++			{
++				pmlmeinfo->scan_cnt = 0;
++				survey_channel = pbuddy_mlmeext->cur_channel;
++				stay_buddy_ch = 1;
++			}
++			else
++			{
++				if( pmlmeinfo->scan_cnt == 0 )
++					stay_buddy_ch = 2;
++				pmlmeinfo->scan_cnt++;
++			}
++		}
++#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++#endif //CONFIG_CONCURRENT_MODE
++		if(pmlmeext->sitesurvey_res.channel_idx == 0)
++		{
++			set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
++		}
++		else
++		{
++			SelectChannel(padapter, survey_channel);
++		}
++
++#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++		if( stay_buddy_ch == 1 )
++		{
++			val8 = 0; //survey done
++			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
++
++			if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
++				check_buddy_fwstate(padapter, _FW_LINKED))
++			{
++				update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
++			}
++		}
++		else if( stay_buddy_ch == 2 )
++		{
++			val8 = 1; //under site survey
++			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
++		}
++#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++
++		if(ScanType == SCAN_ACTIVE) //obey the channel plan setting...
++		{
++			#ifdef CONFIG_P2P
++			if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
++				rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
++			)
++			{
++				issue_probereq_p2p(padapter, NULL);
++				issue_probereq_p2p(padapter, NULL);
++				issue_probereq_p2p(padapter, NULL);
++			}
++			else
++			#endif //CONFIG_P2P
++			{
++				int i;
++				for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
++					if(pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
++						//todo: to issue two probe req???
++						issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
++						//rtw_msleep_os(SURVEY_TO>>1);
++						issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
++					} else {
++						break;
++					}
++				}
++
++				if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
++					//todo: to issue two probe req???
++					issue_probereq(padapter, NULL, NULL);
++					//rtw_msleep_os(SURVEY_TO>>1);
++					issue_probereq(padapter, NULL, NULL);
++				}
++			}
++		}
++
++#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++		if( stay_buddy_ch == 1 )
++			set_survey_timer(pmlmeext, pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND );
++		else
++#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++			set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
++
++	}
++	else
++	{
++
++		//	channel number is 0 or this channel is not valid.
++
++#ifdef CONFIG_CONCURRENT_MODE
++		u8 cur_channel;
++		u8 cur_bwmode;
++		u8 cur_ch_offset;
++
++		if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0)
++		{
++			if (0)
++			DBG_871X(FUNC_ADPT_FMT" back to linked union - ch:%u, bw:%u, offset:%u\n",
++				FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
++		}
++		#ifdef CONFIG_IOCTL_CFG80211
++		else if(padapter->pbuddy_adapter
++			&& pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211
++			&& wdev_to_priv(pbuddy_adapter->rtw_wdev)->p2p_enabled
++			&& rtw_p2p_chk_state(&pbuddy_adapter->wdinfo, P2P_STATE_LISTEN)
++			)
++		{
++			cur_channel = pbuddy_adapter->wdinfo.listen_channel;
++			cur_bwmode = pbuddy_mlmeext->cur_bwmode;
++			cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
++		}
++		#endif
++		else
++		{
++			cur_channel = pmlmeext->cur_channel;
++			cur_bwmode = pmlmeext->cur_bwmode;
++			cur_ch_offset = pmlmeext->cur_ch_offset;
++		}
++#endif
++
++
++#ifdef CONFIG_P2P
++		if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
++		{
++			if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
++			{
++				//	Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT.
++				//	This will let the following flow to run the scanning end.
++				rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
++			}
++			#ifdef CONFIG_DBG_P2P
++			DBG_871X( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt );
++			#endif
++		}
++
++		if(rtw_p2p_findphase_ex_is_needed(pwdinfo))
++		{
++			//	Set the P2P State to the listen state of find phase and set the current channel to the listen channel
++			set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
++			rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
++			pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
++
++			//turn on dynamic functions
++			Restore_DM_Func_Flag(padapter);
++			//Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE);
++
++			_set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) );
++		}
++		else
++#endif //CONFIG_P2P
++		{
++
++#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
++			pmlmeinfo->scan_cnt = 0;
++#endif //CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE
++
++#ifdef CONFIG_ANTENNA_DIVERSITY
++			// 20100721:Interrupt scan operation here.
++			// For SW antenna diversity before link, it needs to switch to another antenna and scan again.
++			// It compares the scan result and select beter one to do connection.
++			if(rtw_hal_antdiv_before_linked(padapter))
++			{
++				pmlmeext->sitesurvey_res.bss_cnt = 0;
++				pmlmeext->sitesurvey_res.channel_idx = -1;
++				pmlmeext->chan_scan_time = SURVEY_TO /2;
++				set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
++				return;
++			}
++#endif
++
++#ifdef CONFIG_P2P
++			if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
++			{
++			#ifdef CONFIG_CONCURRENT_MODE
++				if( pwdinfo->driver_interface == DRIVER_WEXT )
++				{
++					if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
++					{
++						_set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
++					}
++				}
++				rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
++			#else
++				rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
++			#endif
++			}
++			rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
++#endif //CONFIG_P2P
++
++			pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
++
++			//switch back to the original channel
++			//SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
++
++			{
++#ifdef CONFIG_CONCURRENT_MODE
++				set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
++#else
++#ifdef CONFIG_DUALMAC_CONCURRENT
++				dc_set_channel_bwmode_survey_done(padapter);
++#else
++				if( pwdinfo->driver_interface == DRIVER_WEXT )
++				{
++					if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
++					{
++						set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
++					}
++					else
++						set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
++				}
++				else if( pwdinfo->driver_interface == DRIVER_CFG80211 )
++				{
++					set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
++				}
++#endif //CONFIG_DUALMAC_CONCURRENT
++#endif //CONFIG_CONCURRENT_MODE
++			}
++
++			//flush 4-AC Queue after site_survey
++			//val8 = 0;
++			//rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8));
++
++			val8 = 0; //survey done
++			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
++
++			//config MSR
++			Set_MSR(padapter, (pmlmeinfo->state & 0x3));
++
++
++#ifdef CONFIG_IOCTL_CFG80211
++			if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE)
++			{
++				restore_initial_gain = 0;
++			}
++#endif //CONFIG_IOCTL_CFG80211
++
++			if(restore_initial_gain == 1)
++			{
++				initialgain = 0xff; //restore RX GAIN
++				rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
++			}
++
++			//turn on dynamic functions
++			Restore_DM_Func_Flag(padapter);
++			//Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE);
++
++			if (is_client_associated_to_ap(padapter) == _TRUE)
++			{
++				issue_nulldata(padapter, NULL, 0, 3, 500);
++
++#ifdef CONFIG_CONCURRENT_MODE
++				if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
++				{
++					DBG_871X("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n");
++
++					issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
++				}
++#endif
++			}
++#ifdef CONFIG_CONCURRENT_MODE
++			else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
++			{
++				issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
++			}
++#endif
++
++			report_surveydone_event(padapter);
++
++			pmlmeext->chan_scan_time = SURVEY_TO;
++			pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
++
++			issue_action_BSSCoexistPacket(padapter);
++			issue_action_BSSCoexistPacket(padapter);
++			issue_action_BSSCoexistPacket(padapter);
++
++		}
++
++#ifdef CONFIG_CONCURRENT_MODE
++		if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
++			check_buddy_fwstate(padapter, _FW_LINKED))
++		{
++
++			DBG_871X("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
++
++			DBG_871X("restart pbuddy_adapter's beacon\n");
++
++			update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
++		}
++#endif
++
++	}
++
++	return;
++
++}
++
++//collect bss info from Beacon and Probe response frames.
++u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
++{
++	int	i;
++	u32	len;
++	u8	*p;
++	u16	val16, subtype;
++	u8	*pframe = precv_frame->u.hdr.rx_data;
++	u32	packet_len = precv_frame->u.hdr.len;
++	struct registry_priv 	*pregistrypriv = &padapter->registrypriv;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
++
++	if (len > MAX_IE_SZ)
++	{
++		//DBG_871X("IE too long for survey event\n");
++		return _FAIL;
++	}
++
++	_rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
++
++	subtype = GetFrameSubType(pframe);
++
++	if(subtype==WIFI_BEACON)
++		bssid->Reserved[0] = 1;
++	else
++		bssid->Reserved[0] = 0;
++
++	bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
++
++	//below is to copy the information element
++	bssid->IELength = len;
++	_rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
++
++	//get the signal strength
++	bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.signal_qual;//in percentage
++	bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.signal_strength;//in percentage
++	bssid->Rssi = precv_frame->u.hdr.attrib.RecvSignalPower; // in dBM.raw data
++
++#ifdef CONFIG_ANTENNA_DIVERSITY
++	//rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna));
++	rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA,  &bssid->PhyInfo.Optimum_antenna);
++#endif
++
++	// checking SSID
++	if ((p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SSID_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_)) == NULL)
++	{
++		DBG_871X("marc: cannot find SSID for survey event\n");
++		return _FAIL;
++	}
++
++	if (*(p + 1))
++	{
++		if (len > NDIS_802_11_LENGTH_SSID)
++		{
++			DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
++			return _FAIL;
++		}
++		_rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
++		bssid->Ssid.SsidLength = *(p + 1);
++	}
++	else
++	{
++		bssid->Ssid.SsidLength = 0;
++	}
++
++	_rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
++
++	//checking rate info...
++	i = 0;
++	p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
++	if (p != NULL)
++	{
++		if (len > NDIS_802_11_LENGTH_RATES_EX)
++		{
++			DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
++			return _FAIL;
++		}
++		_rtw_memcpy(bssid->SupportedRates, (p + 2), len);
++		i = len;
++	}
++
++	p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
++	if (p != NULL)
++	{
++		if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
++		{
++			DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
++			return _FAIL;
++		}
++		_rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
++	}
++
++	//todo:
++#if 0
++	if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
++	{
++		bssid->NetworkTypeInUse = Ndis802_11DS;
++	}
++	else
++#endif
++	{
++		bssid->NetworkTypeInUse = Ndis802_11OFDM24;
++	}
++
++	if (bssid->IELength < 12)
++		return _FAIL;
++
++	// Checking for DSConfig
++	p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _DSSET_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
++
++	bssid->Configuration.DSConfig = 0;
++	bssid->Configuration.Length = 0;
++
++	if (p)
++	{
++		bssid->Configuration.DSConfig = *(p + 2);
++	}
++	else
++	{// In 5G, some ap do not have DSSET IE
++		// checking HT info for channel
++		p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_ADD_INFO_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
++		if(p)
++		{
++			struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
++			bssid->Configuration.DSConfig = HT_info->primary_channel;
++		}
++		else
++		{ // use current channel
++			bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
++		}
++	}
++
++	_rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
++	bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
++
++	val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
++
++	if (val16 & BIT(0))
++	{
++		bssid->InfrastructureMode = Ndis802_11Infrastructure;
++		_rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
++	}
++	else
++	{
++		bssid->InfrastructureMode = Ndis802_11IBSS;
++		_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
++	}
++
++	if (val16 & BIT(4))
++		bssid->Privacy = 1;
++	else
++		bssid->Privacy = 0;
++
++	bssid->Configuration.ATIMWindow = 0;
++
++	//20/40 BSS Coexistence check
++	if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
++	{
++		struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
++
++		p = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
++		if(p && len>0)
++		{
++			struct HT_caps_element	*pHT_caps;
++			pHT_caps = (struct HT_caps_element	*)(p + 2);
++
++			if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
++			{
++				pmlmepriv->num_FortyMHzIntolerant++;
++			}
++		}
++		else
++		{
++			pmlmepriv->num_sta_no_ht++;
++		}
++
++	}
++
++#ifdef CONFIG_INTEL_WIDI
++	//process_intel_widi_query_or_tigger(padapter, bssid);
++	if(process_intel_widi_query_or_tigger(padapter, bssid))
++	{
++		return _FAIL;
++	}
++#endif // CONFIG_INTEL_WIDI
++
++	#if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
++	if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
++		DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
++			, bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
++			, rtw_get_oper_ch(padapter)
++			, bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
++		);
++	}
++	#endif
++
++	// mark bss info receving from nearby channel as SignalQuality 101
++	if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
++	{
++		bssid->PhyInfo.SignalQuality= 101;
++	}
++
++	return _SUCCESS;
++}
++
++void start_create_ibss(_adapter* padapter)
++{
++	unsigned short	caps;
++	u8	val8;
++	u8	join_type;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
++	pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
++	pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
++
++	//update wireless mode
++	update_wireless_mode(padapter);
++
++	//udpate capability
++	caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
++	update_capinfo(padapter, caps);
++	if(caps&cap_IBSS)//adhoc master
++	{
++		//set_opmode_cmd(padapter, adhoc);//removed
++
++		val8 = 0xcf;
++		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
++
++		//switch channel
++		//SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
++		set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
++
++		beacon_timing_control(padapter);
++
++		//set msr to WIFI_FW_ADHOC_STATE
++		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
++		Set_MSR(padapter, (pmlmeinfo->state & 0x3));
++
++		//issue beacon
++		if(send_beacon(padapter)==_FAIL)
++		{
++			RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
++
++			report_join_res(padapter, -1);
++			pmlmeinfo->state = WIFI_FW_NULL_STATE;
++		}
++		else
++		{
++			rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
++			join_type = 0;
++			rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
++
++			report_join_res(padapter, 1);
++			pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
++		}
++	}
++	else
++	{
++		DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
++		return;
++	}
++
++}
++
++void start_clnt_join(_adapter* padapter)
++{
++	unsigned short	caps;
++	u8	val8;
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	WLAN_BSSID_EX		*pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
++
++	//update wireless mode
++	update_wireless_mode(padapter);
++
++	//udpate capability
++	caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
++	update_capinfo(padapter, caps);
++	if (caps&cap_ESS)
++	{
++		Set_MSR(padapter, WIFI_FW_STATION_STATE);
++
++		val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
++		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
++
++		#ifdef CONFIG_DEAUTH_BEFORE_CONNECT
++		// Because of AP's not receiving deauth before
++		// AP may: 1)not response auth or 2)deauth us after link is complete
++		// issue deauth before issuing auth to deal with the situation
++
++		//	Commented by Albert 2012/07/21
++		//	For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
++		{
++			#ifdef CONFIG_P2P
++			_queue *queue = &(padapter->mlmepriv.scanned_queue);
++			_list	*head = get_list_head(queue);
++			_list *pos = get_next(head);
++			struct wlan_network *scanned = NULL;
++			u8 ie_offset = 0;
++			_irqL irqL;
++			bool has_p2p_ie = _FALSE;
++
++			_enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
++
++			for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
++
++				scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
++				if(scanned==NULL)
++					rtw_warn_on(1);
++
++				if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
++					&& _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
++				) {
++					ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
++					if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
++						has_p2p_ie = _TRUE;
++					break;
++				}
++			}
++
++			_exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
++
++			if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
++			#endif /* CONFIG_P2P */
++				issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
++		}
++		#endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
++
++		//here wait for receiving the beacon to start auth
++		//and enable a timer
++		set_link_timer(pmlmeext, decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval));
++
++		pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
++	}
++	else if (caps&cap_IBSS) //adhoc client
++	{
++		Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
++
++		val8 = 0xcf;
++		rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
++
++		//switch channel
++		set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
++
++		beacon_timing_control(padapter);
++
++		pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
++
++		report_join_res(padapter, 1);
++	}
++	else
++	{
++		//DBG_871X("marc: invalid cap:%x\n", caps);
++		return;
++	}
++
++}
++
++void start_clnt_auth(_adapter* padapter)
++{
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	_cancel_timer_ex(&pmlmeext->link_timer);
++
++	pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
++	pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
++
++	pmlmeinfo->auth_seq = 1;
++	pmlmeinfo->reauth_count = 0;
++	pmlmeinfo->reassoc_count = 0;
++	pmlmeinfo->link_count = 0;
++	pmlmeext->retry = 0;
++
++
++	issue_auth(padapter, NULL, 0);
++
++	set_link_timer(pmlmeext, REAUTH_TO);
++
++}
++
++
++void start_clnt_assoc(_adapter* padapter)
++{
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	_cancel_timer_ex(&pmlmeext->link_timer);
++
++	pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
++	pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
++
++	issue_assocreq(padapter);
++
++	set_link_timer(pmlmeext, REASSOC_TO);
++}
++
++unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
++{
++	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++
++	//check A3
++	if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
++		return _SUCCESS;
++
++	DBG_871X("%s\n", __FUNCTION__);
++
++	if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
++	{
++		if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
++		{
++			pmlmeinfo->state = WIFI_FW_NULL_STATE;
++			report_del_sta_event(padapter, MacAddr, reason);
++
++		}
++		else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
++		{
++			pmlmeinfo->state = WIFI_FW_NULL_STATE;
++			report_join_res(padapter, -2);
++		}
++	}
++
++	return _SUCCESS;
++}
++
++#ifdef CONFIG_80211D
++static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
++{
++	struct registry_priv *pregistrypriv;
++	struct mlme_ext_priv *pmlmeext;
++	RT_CHANNEL_INFO *chplan_new;
++	u8 channel;
++	u8 i;
++
++
++	pregistrypriv = &padapter->registrypriv;
++	pmlmeext = &padapter->mlmeextpriv;
++
++	// Adjust channel plan by AP Country IE
++	if (pregistrypriv->enable80211d &&
++		(!pmlmeext->update_channel_plan_by_ap_done))
++	{
++		u8 *ie, *p;
++		u32 len;
++		RT_CHANNEL_PLAN chplan_ap;
++		RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
++		u8 country[4];
++		u8 fcn; // first channel number
++		u8 noc; // number of channel
++		u8 j, k;
++
++		ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
++		if (!ie) return;
++		if (len < 6) return;
++
++		ie += 2;
++		p = ie;
++		ie += len;
++
++		_rtw_memset(country, 0, 4);
++		_rtw_memcpy(country, p, 3);
++		p += 3;
++		RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
++				("%s: 802.11d country=%s\n", __FUNCTION__, country));
++
++		i = 0;
++		while ((ie - p) >= 3)
++		{
++			fcn = *(p++);
++			noc = *(p++);
++			p++;
++
++			for (j = 0; j < noc; j++)
++			{
++				if (fcn <= 14) channel = fcn + j; // 2.4 GHz
++				else channel = fcn + j*4; // 5 GHz
++
++				chplan_ap.Channel[i++] = channel;
++			}
++		}
++		chplan_ap.Len = i;
++
++#ifdef CONFIG_DEBUG_RTL871X
++#ifdef PLATFORM_LINUX
++		i = 0;
++		printk("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid);
++		while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
++		{
++			printk("%02d,", chplan_ap.Channel[i]);
++			i++;
++		}
++		printk("}\n");
++#endif
++#endif
++
++		_rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
++#ifdef CONFIG_DEBUG_RTL871X
++#ifdef PLATFORM_LINUX
++		i = 0;
++		printk("%s: STA channel plan {", __func__);
++		while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
++		{
++			printk("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
++			i++;
++		}
++		printk("}\n");
++#endif
++#endif
++
++		_rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
++		chplan_new = pmlmeext->channel_set;
++
++		i = j = k = 0;
++		if (pregistrypriv->wireless_mode & WIRELESS_11G)
++		{
++			do {
++				if ((i == MAX_CHANNEL_NUM) ||
++					(chplan_sta[i].ChannelNum == 0) ||
++					(chplan_sta[i].ChannelNum > 14))
++					break;
++
++				if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
++					break;
++
++				if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
++				{
++					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
++					chplan_new[k].ScanType = SCAN_ACTIVE;
++					i++;
++					j++;
++					k++;
++				}
++				else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
++				{
++					chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
++//					chplan_new[k].ScanType = chplan_sta[i].ScanType;
++					chplan_new[k].ScanType = SCAN_PASSIVE;
++					i++;
++					k++;
++				}
++				else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
++				{
++					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
++					chplan_new[k].ScanType = SCAN_ACTIVE;
++					j++;
++					k++;
++				}
++			} while (1);
++
++			// change AP not support channel to Passive scan
++			while ((i < MAX_CHANNEL_NUM) &&
++				(chplan_sta[i].ChannelNum != 0) &&
++				(chplan_sta[i].ChannelNum <= 14))
++			{
++				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
++//				chplan_new[k].ScanType = chplan_sta[i].ScanType;
++				chplan_new[k].ScanType = SCAN_PASSIVE;
++				i++;
++				k++;
++			}
++
++			// add channel AP supported
++			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
++			{
++				chplan_new[k].ChannelNum = chplan_ap.Channel[j];
++				chplan_new[k].ScanType = SCAN_ACTIVE;
++				j++;
++				k++;
++			}
++		}
++		else
++		{
++			// keep original STA 2.4G channel plan
++			while ((i < MAX_CHANNEL_NUM) &&
++				(chplan_sta[i].ChannelNum != 0) &&
++				(chplan_sta[i].ChannelNum <= 14))
++			{
++				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
++				chplan_new[k].ScanType = chplan_sta[i].ScanType;
++				i++;
++				k++;
++			}
++
++			// skip AP 2.4G channel plan
++			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
++			{
++				j++;
++			}
++		}
++
++		if (pregistrypriv->wireless_mode & WIRELESS_11A)
++		{
++			do {
++				if ((i == MAX_CHANNEL_NUM) ||
++					(chplan_sta[i].ChannelNum == 0))
++					break;
++
++				if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
++					break;
++
++				if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
++				{
++					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
++					chplan_new[k].ScanType = SCAN_ACTIVE;
++					i++;
++					j++;
++					k++;
++				}
++				else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
++				{
++					chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
++//					chplan_new[k].ScanType = chplan_sta[i].ScanType;
++					chplan_new[k].ScanType = SCAN_PASSIVE;
++					i++;
++					k++;
++				}
++				else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
++				{
++					chplan_new[k].ChannelNum = chplan_ap.Channel[j];
++					chplan_new[k].ScanType = SCAN_ACTIVE;
++					j++;
++					k++;
++				}
++			} while (1);
++
++			// change AP not support channel to Passive scan
++			while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
++			{
++				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
++//				chplan_new[k].ScanType = chplan_sta[i].ScanType;
++				chplan_new[k].ScanType = SCAN_PASSIVE;
++				i++;
++				k++;
++			}
++
++			// add channel AP supported
++			while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0))
++			{
++				chplan_new[k].ChannelNum = chplan_ap.Channel[j];
++				chplan_new[k].ScanType = SCAN_ACTIVE;
++				j++;
++				k++;
++			}
++		}
++		else
++		{
++			// keep original STA 5G channel plan
++			while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
++			{
++				chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
++				chplan_new[k].ScanType = chplan_sta[i].ScanType;
++				i++;
++				k++;
++			}
++		}
++
++		pmlmeext->update_channel_plan_by_ap_done = 1;
++
++#ifdef CONFIG_DEBUG_RTL871X
++#ifdef PLATFORM_LINUX
++		k = 0;
++		printk("%s: new STA channel plan {", __func__);
++		while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
++		{
++			printk("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
++			k++;
++		}
++		printk("}\n");
++#endif
++#endif
++
++#if 0
++		// recover the right channel index
++		channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
++		k = 0;
++		while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0))
++		{
++			if (chplan_new[k].ChannelNum == channel) {
++				RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
++						 ("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
++						  __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k));
++				pmlmeext->sitesurvey_res.channel_idx = k;
++				break;
++			}
++			k++;
++		}
++#endif
++	}
++
++	// If channel is used by AP, set channel scan type to active
++	channel = bssid->Configuration.DSConfig;
++	chplan_new = pmlmeext->channel_set;
++	i = 0;
++	while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0))
++	{
++		if (chplan_new[i].ChannelNum == channel)
++		{
++			if (chplan_new[i].ScanType == SCAN_PASSIVE)
++			{
++				//5G Bnad 2, 3 (DFS) doesn't change to active scan
++				if(channel >= 52 && channel <= 144)
++					break;
++
++				chplan_new[i].ScanType = SCAN_ACTIVE;
++				RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
++						 ("%s: change channel %d scan type from passive to active\n",
++						  __FUNCTION__, channel));
++			}
++			break;
++		}
++		i++;
++	}
++}
++#endif
++
++/****************************************************************************
++
++Following are the functions to report events
++
++*****************************************************************************/
++
++void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
++{
++	struct cmd_obj *pcmd_obj;
++	u8	*pevtcmd;
++	u32 cmdsz;
++	struct survey_event	*psurvey_evt;
++	struct C2HEvent_Header *pc2h_evt_hdr;
++	struct mlme_ext_priv *pmlmeext;
++	struct cmd_priv *pcmdpriv;
++	//u8 *pframe = precv_frame->u.hdr.rx_data;
++	//uint len = precv_frame->u.hdr.len;
++
++	if(!padapter)
++		return;
++
++	pmlmeext = &padapter->mlmeextpriv;
++	pcmdpriv = &padapter->cmdpriv;
++
++
++	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
++	{
++		return;
++	}
++
++	cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
++	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
++	{
++		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
++		return;
++	}
++
++	_rtw_init_listhead(&pcmd_obj->list);
++
++	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
++	pcmd_obj->cmdsz = cmdsz;
++	pcmd_obj->parmbuf = pevtcmd;
++
++	pcmd_obj->rsp = NULL;
++	pcmd_obj->rspsz  = 0;
++
++	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
++	pc2h_evt_hdr->len = sizeof(struct survey_event);
++	pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
++	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
++
++	psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
++
++	if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL)
++	{
++		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
++		rtw_mfree((u8 *)pevtcmd, cmdsz);
++		return;
++	}
++
++#ifdef CONFIG_80211D
++	process_80211d(padapter, &psurvey_evt->bss);
++#endif
++
++	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
++
++	pmlmeext->sitesurvey_res.bss_cnt++;
++
++	return;
++
++}
++
++void report_surveydone_event(_adapter *padapter)
++{
++	struct cmd_obj *pcmd_obj;
++	u8	*pevtcmd;
++	u32 cmdsz;
++	struct surveydone_event *psurveydone_evt;
++	struct C2HEvent_Header	*pc2h_evt_hdr;
++	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
++	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
++
++	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
++	{
++		return;
++	}
++
++	cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
++	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
++	{
++		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
++		return;
++	}
++
++	_rtw_init_listhead(&pcmd_obj->list);
++
++	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
++	pcmd_obj->cmdsz = cmdsz;
++	pcmd_obj->parmbuf = pevtcmd;
++
++	pcmd_obj->rsp = NULL;
++	pcmd_obj->rspsz  = 0;
++
++	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
++	pc2h_evt_hdr->len = sizeof(struct surveydone_event);
++	pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
++	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
++
++	psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
++	psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
++
++	DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
++
++	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
++
++	return;
++
++}
++
++void report_join_res(_adapter *padapter, int res)
++{
++	struct cmd_obj *pcmd_obj;
++	u8	*pevtcmd;
++	u32 cmdsz;
++	struct joinbss_event		*pjoinbss_evt;
++	struct C2HEvent_Header	*pc2h_evt_hdr;
++	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
++	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
++	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
++
++	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
++	{
++		return;
++	}
++
++	cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
++	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
++	{
++		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
++		return;
++	}
++
++	_rtw_init_listhead(&pcmd_obj->list);
++
++	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
++	pcmd_obj->cmdsz = cmdsz;
++	pcmd_obj->parmbuf = pevtcmd;
++
++	pcmd_obj->rsp = NULL;
++	pcmd_obj->rspsz  = 0;
++
++	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
++	pc2h_evt_hdr->len = sizeof(struct joinbss_event);
++	pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
++	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
++
++	pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
++	_rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
++	pjoinbss_evt->network.join_res 	= pjoinbss_evt->network.aid = res;
++
++	DBG_871X("report_join_res(%d)\n", res);
++
++
++	rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
++
++
++	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
++
++	return;
++
++}
++
++void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
++{
++	struct cmd_obj *pcmd_obj;
++	u8	*pevtcmd;
++	u32 cmdsz;
++	struct sta_info *psta;
++	int	mac_id;
++	struct stadel_event			*pdel_sta_evt;
++	struct C2HEvent_Header	*pc2h_evt_hdr;
++	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
++	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
++
++	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
++	{
++		return;
++	}
++
++	cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
++	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
++	{
++		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
++		return;
++	}
++
++	_rtw_init_listhead(&pcmd_obj->list);
++
++	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
++	pcmd_obj->cmdsz = cmdsz;
++	pcmd_obj->parmbuf = pevtcmd;
++
++	pcmd_obj->rsp = NULL;
++	pcmd_obj->rspsz  = 0;
++
++	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
++	pc2h_evt_hdr->len = sizeof(struct stadel_event);
++	pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
++	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
++
++	pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
++	_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
++	_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
++
++
++	psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
++	if(psta)
++		mac_id = (int)psta->mac_id;
++	else
++		mac_id = (-1);
++
++	pdel_sta_evt->mac_id = mac_id;
++
++	DBG_871X("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
++
++	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
++
++	return;
++}
++
++void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
++{
++	struct cmd_obj *pcmd_obj;
++	u8	*pevtcmd;
++	u32 cmdsz;
++	struct stassoc_event		*padd_sta_evt;
++	struct C2HEvent_Header	*pc2h_evt_hdr;
++	struct mlme_ext_priv		*pmlmeext = &padapter->mlmeextpriv;
++	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
++
++	if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
++	{
++		return;
++	}
++
++	cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
++	if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
++	{
++		rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
++		return;
++	}
++
++	_rtw_init_listhead(&pcmd_obj->list);
++
++	pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
++	pcmd_obj->cmdsz = cmdsz;
++	pcmd_obj->parmbuf = pevtcmd;
++
++	pcmd_obj->rsp = NULL;
++	pcmd_obj->rspsz  = 0;
++
++	pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
++	pc2h_evt_hdr->len = sizeof(struct stassoc_event);
++	pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
++	pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
++
++	padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
++	_rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
++	padd_sta_evt->cam_id = cam_idx;
++
++	DBG_871X("report_add_sta_event: add STA\n");
++
++	rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
++
++	return;
++}
++
++
++/****************************************************************************
++
++Following are the event callback functions
++
++*****************************************************************************/
++
++//for sta/adhoc mode
++void update_sta_info(_adapter *padapter, struct sta_info *psta)
++{
++	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
++	struct mlme_ext_priv	*pmlmeext